[clang] 71e6e82 - [clang] Fix constrained decltype(auto) deduction

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 5 18:20:24 PST 2021


Author: Matheus Izvekov
Date: 2021-03-05T18:20:09-08:00
New Revision: 71e6e82746caba1a40a0faeb43fe0c0a1fadb77e

URL: https://github.com/llvm/llvm-project/commit/71e6e82746caba1a40a0faeb43fe0c0a1fadb77e
DIFF: https://github.com/llvm/llvm-project/commit/71e6e82746caba1a40a0faeb43fe0c0a1fadb77e.diff

LOG: [clang] Fix constrained decltype(auto) deduction

Prior to this fix, constrained decltype(auto) behaves exactly the same
as constrained regular auto.
This fixes it so it deduces like decltype(auto).

Signed-off-by: Matheus Izvekov <mizvekov at gmail.com>

Reviewed By: rsmith

Differential Revision: https://reviews.llvm.org/D98087

Added: 
    

Modified: 
    clang/lib/Sema/SemaType.cpp
    clang/test/CXX/dcl/dcl.fct/p17.cpp
    clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
    clang/test/Parser/cxx2a-placeholder-type-constraint.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 0016c1aa541c..0eafff4dbccf 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -1269,11 +1269,10 @@ static QualType ConvertConstrainedAutoDeclSpecToType(Sema &S, DeclSpec &DS,
   llvm::SmallVector<TemplateArgument, 8> TemplateArgs;
   for (auto &ArgLoc : TemplateArgsInfo.arguments())
     TemplateArgs.push_back(ArgLoc.getArgument());
-  return S.Context.getAutoType(QualType(), AutoTypeKeyword::Auto, false,
-                               /*IsPack=*/false,
-                               cast<ConceptDecl>(TemplateId->Template.get()
-                                                 .getAsTemplateDecl()),
-                               TemplateArgs);
+  return S.Context.getAutoType(
+      QualType(), AutoKW, false, /*IsPack=*/false,
+      cast<ConceptDecl>(TemplateId->Template.get().getAsTemplateDecl()),
+      TemplateArgs);
 }
 
 /// Convert the specified declspec to the appropriate type

diff  --git a/clang/test/CXX/dcl/dcl.fct/p17.cpp b/clang/test/CXX/dcl/dcl.fct/p17.cpp
index 0ce45cd5b77d..d7487233f5d5 100644
--- a/clang/test/CXX/dcl/dcl.fct/p17.cpp
+++ b/clang/test/CXX/dcl/dcl.fct/p17.cpp
@@ -186,7 +186,7 @@ namespace constrained {
   static_assert(is_same_v<decltype(f9(i, c)), void>);
   // expected-error at -1{{no matching}}
   static_assert(is_same_v<decltype(f9(i, i, ci)), void>);
-  void f10(C decltype(auto) x);
+  void f10(C decltype(auto) x); // expected-error{{decltype(auto)' not allowed in function prototype}}
   auto f11 = [] (C auto x) { };
   // expected-note at -1{{candidate template ignored}} expected-note at -1{{because}}
   static_assert(is_same_v<decltype(f11(1)), void>);
@@ -238,7 +238,7 @@ namespace constrained {
   static_assert(is_same_v<decltype(f20(i, c)), void>);
   // expected-error at -1{{no matching}}
   static_assert(is_same_v<decltype(f20(c, c, cc)), void>);
-  void f21(C2<char> decltype(auto) x);
+  void f21(C2<char> decltype(auto) x); // expected-error{{decltype(auto)' not allowed in function prototype}}
   auto f22 = [] (C2<char> auto x) { };
   // expected-note at -1{{candidate template ignored}} expected-note at -1{{because}}
   static_assert(is_same_v<decltype(f22(1)), void>);

diff  --git a/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp b/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
index ae194670954c..44539bd125ff 100644
--- a/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
+++ b/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
@@ -1,4 +1,6 @@
 // RUN:  %clang_cc1 -std=c++2a -verify %s
+template<typename T, typename U> constexpr bool is_same_v = false;
+template<typename T> constexpr bool is_same_v<T, T> = true;
 
 template<typename T, unsigned size>
 concept LargerThan = sizeof(T) > size;
@@ -41,4 +43,28 @@ Large auto test5() -> void;
 auto test6() -> Large auto { return 1; }
 
 X::Small auto test7() { return 'a'; }
-X::SmallerThan<5> auto test8() { return 10; }
\ No newline at end of file
+X::SmallerThan<5> auto test8() { return 10; }
+
+namespace PR48384 {
+  int a = 0;
+  int &b = a;
+  template <class T> concept True = true;
+
+  True auto c = a;
+  static_assert(is_same_v<decltype(c), int>);
+
+  True auto d = b;
+  static_assert(is_same_v<decltype(d), int>);
+
+  True decltype(auto) e = a;
+  static_assert(is_same_v<decltype(e), int>);
+
+  True decltype(auto) f = b;
+  static_assert(is_same_v<decltype(f), int&>);
+
+  True decltype(auto) g = (a);
+  static_assert(is_same_v<decltype(g), int&>);
+
+  True decltype(auto) h = (b);
+  static_assert(is_same_v<decltype(h), int&>);
+}

diff  --git a/clang/test/Parser/cxx2a-placeholder-type-constraint.cpp b/clang/test/Parser/cxx2a-placeholder-type-constraint.cpp
index dc1d75e1d960..64b09e372059 100644
--- a/clang/test/Parser/cxx2a-placeholder-type-constraint.cpp
+++ b/clang/test/Parser/cxx2a-placeholder-type-constraint.cpp
@@ -23,13 +23,13 @@ int foo() {
   {C<> decltype(auto) a = 1;}
   {C<int> decltype(auto) a = 1;}
   {const C<> decltype(auto) &a = 1;} // expected-error{{'decltype(auto)' cannot be combined with other type specifiers}}
-  // expected-error at -1{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
+  // expected-error at -1{{cannot form reference to 'decltype(auto)'}}
   {const C<int> decltype(auto) &a = 1;} // expected-error{{'decltype(auto)' cannot be combined with other type specifiers}}
-  // expected-error at -1{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
+  // expected-error at -1{{cannot form reference to 'decltype(auto)'}}
   {C a = 1;}
   // expected-error at -1{{expected 'auto' or 'decltype(auto)' after concept name}}
   {C decltype a19 = 1;}
   // expected-error at -1{{expected '('}}
   {C decltype(1) a20 = 1;}
   // expected-error at -1{{expected 'auto' or 'decltype(auto)' after concept name}}
-}
\ No newline at end of file
+}


        


More information about the cfe-commits mailing list