[clang] 94fd00f - [Concepts] Fix placeholder constraints when references are involved

Roy Jacobson via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 23 08:15:04 PDT 2022


Author: Roy Jacobson
Date: 2022-03-23T11:14:58-04:00
New Revision: 94fd00f41ebddf84148f494410130527169d9573

URL: https://github.com/llvm/llvm-project/commit/94fd00f41ebddf84148f494410130527169d9573
DIFF: https://github.com/llvm/llvm-project/commit/94fd00f41ebddf84148f494410130527169d9573.diff

LOG: [Concepts] Fix placeholder constraints when references are involved

Placeholder types were not checked for constraint satisfaction when modified by references or pointers.
The behavior now matches that of GCC and MSVC.

Are there other modifiers we might need to "peel"? I'm not sure my approach to this is the 'right' way to fix this, the loop feels a bit clunky.

GitHub issues [[ https://github.com/llvm/llvm-project/issues/54443 | #54443 ]], [[ https://github.com/llvm/llvm-project/issues/53911 | #53911 ]]

Reviewed By: erichkeane

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

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaTemplateDeduction.cpp
    clang/test/SemaTemplate/concepts.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 403bc08eec9be..865da1eb2aa1b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -65,6 +65,10 @@ Bug Fixes
   fixes `Issue 53044 <https://github.com/llvm/llvm-project/issues/53044>`_.
 - Allow `-Wno-gnu` to silence GNU extension diagnostics for pointer arithmetic
   diagnostics. Fixes `Issue 54444 <https://github.com/llvm/llvm-project/issues/54444>`_.
+- Placeholder constraints, as in `Concept auto x = f();`, were not checked when modifiers
+  like ``auto&`` or ``auto**`` were added. These constraints are now checked.
+  This fixes  `Issue 53911 <https://github.com/llvm/llvm-project/issues/53911>`_
+  and  `Issue 54443 <https://github.com/llvm/llvm-project/issues/54443>`_.
 
 Improvements to Clang's diagnostics
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index a53d83ea700b6..cb273aa285906 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4769,12 +4769,13 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result,
       return DAR_FailedAlreadyDiagnosed;
   }
 
-  if (const auto *AT = Type.getType()->getAs<AutoType>()) {
+  QualType MaybeAuto = Type.getType().getNonReferenceType();
+  while (MaybeAuto->isPointerType())
+    MaybeAuto = MaybeAuto->getPointeeType();
+  if (const auto *AT = MaybeAuto->getAs<AutoType>()) {
     if (AT->isConstrained() && !IgnoreConstraints) {
-      auto ConstraintsResult =
-          CheckDeducedPlaceholderConstraints(*this, *AT,
-                                             Type.getContainedAutoTypeLoc(),
-                                             DeducedType);
+      auto ConstraintsResult = CheckDeducedPlaceholderConstraints(
+          *this, *AT, Type.getContainedAutoTypeLoc(), DeducedType);
       if (ConstraintsResult != DAR_Succeeded)
         return ConstraintsResult;
     }

diff  --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp
index 132761b2d68ae..23c79421bb6f8 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -171,7 +171,7 @@ namespace PR50561 {
 }
 
 namespace PR49188 {
-  template<class T> concept C = false;     // expected-note 6 {{because 'false' evaluated to false}}
+  template<class T> concept C = false;     // expected-note 7 {{because 'false' evaluated to false}}
 
   C auto f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
     return void();
@@ -189,7 +189,7 @@ namespace PR49188 {
   }
   C decltype(auto) f6() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
   }
-  C auto& f7() { // expected-error {{cannot form a reference to 'void'}}
+  C auto& f7() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
     return void();
   }
   C auto& f8() {
@@ -199,13 +199,16 @@ namespace PR49188 {
   }
 }
 namespace PR53911 {
-  template<class T> concept C = false;
+  template<class T> concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
 
-  C auto *f1() {
-    return (void*)nullptr; // FIXME: should error
+  C auto *f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
+    return (void*)nullptr;
   }
-  C auto *f2() {
-    return (int*)nullptr; // FIXME: should error
+  C auto *f2() { // expected-error {{deduced type 'int' does not satisfy 'C'}}
+    return (int*)nullptr;
+  }
+  C auto *****f3() { // expected-error {{deduced type 'int' does not satisfy 'C'}}
+    return (int*****)nullptr;
   }
 }
 
@@ -222,3 +225,34 @@ struct B {
 };
 void (*f2)() = B::f; // expected-error {{address of overloaded function 'f' does not match required type}}
 }
+
+namespace PR54443 {
+
+template <class T, class U>
+struct is_same { static constexpr bool value = false; };
+
+template <class T>
+struct is_same<T, T> { static constexpr bool value = true; };
+
+template <class T, class U>
+concept same_as = is_same<T, U>::value; // expected-note-re 4 {{because {{.*}} evaluated to false}}
+
+int const &f();
+
+same_as<int const> auto i1 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as<const int>'}}
+same_as<int const> auto &i2 = f();
+same_as<int const> auto &&i3 = f(); // expected-error {{deduced type 'const int &' does not satisfy 'same_as<const int>'}}
+
+same_as<int const &> auto i4 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as<const int &>'}}
+same_as<int const &> auto &i5 = f(); // expected-error {{deduced type 'const int' does not satisfy 'same_as<const int &>'}}
+same_as<int const &> auto &&i6 = f();
+
+template <class T>
+concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
+
+int **const &g();
+
+C auto **j1 = g();   // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto **&j2 = g();  // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto **&&j3 = g(); // expected-error {{deduced type 'int' does not satisfy 'C'}}
+}


        


More information about the cfe-commits mailing list