llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Mital Ashok (MitalAshok)

<details>
<summary>Changes</summary>

Make sure that the functions are instantiated to deduce the return type. Fixes 
#<!-- -->101614

Allow `BuiltinFnTy` in `BuildDecltypeType` (these are wrapped in a 
`DeclRefExpr` that has the actual type). Fixes #<!-- -->101690


---
Full diff: https://github.com/llvm/llvm-project/pull/101702.diff


5 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+1) 
- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+1-1) 
- (modified) clang/lib/Sema/SemaType.cpp (+3-1) 
- (added) clang/test/SemaCXX/builtin-std-move-placeholder-return.cpp (+62) 
- (modified) clang/test/SemaCXX/builtin-std-move.cpp (+4) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 25f5bd37bbe94..a873d8ab0e4e8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -173,6 +173,7 @@ Bug Fixes to C++ Support
 - Clang now correctly parses potentially declarative nested-name-specifiers in 
pointer-to-member declarators.
 - Fix a crash when checking the initialzier of an object that was initialized
   with a string literal. (#GH82167)
+- Clang can now use the definition of ``std::forward_like`` libstdc++ 14.1 and 
14.2. (#GH101614)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index f93cd113988ae..2f9b537814661 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4895,7 +4895,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation 
PointOfInstantiation,
   // Never implicitly instantiate a builtin; we don't actually need a function
   // body.
   if (Function->getBuiltinID() && TSK == TSK_ImplicitInstantiation &&
-      !DefinitionRequired)
+      !DefinitionRequired && !Function->getReturnType()->isUndeducedType())
     return;
 
   // Don't instantiate a definition if we already have one.
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 6fa39cdccef2b..5a2dfc3228690 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -9468,7 +9468,9 @@ QualType Sema::getDecltypeForExpr(Expr *E) {
 }
 
 QualType Sema::BuildDecltypeType(Expr *E, bool AsUnevaluated) {
-  assert(!E->hasPlaceholderType() && "unexpected placeholder");
+  assert((!E->hasPlaceholderType() ||
+          E->getType()->isSpecificBuiltinType(BuiltinType::Kind::BuiltinFn)) &&
+         "unexpected placeholder");
 
   if (AsUnevaluated && CodeSynthesisContexts.empty() &&
       !E->isInstantiationDependent() && E->HasSideEffects(Context, false)) {
diff --git a/clang/test/SemaCXX/builtin-std-move-placeholder-return.cpp 
b/clang/test/SemaCXX/builtin-std-move-placeholder-return.cpp
new file mode 100644
index 0000000000000..62446fdf4f3db
--- /dev/null
+++ b/clang/test/SemaCXX/builtin-std-move-placeholder-return.cpp
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -std=c++23 -verify %s -DPLACEHOLDER="decltype(auto)"
+// RUN: %clang_cc1 -std=c++23 -verify %s -DPLACEHOLDER="auto&&"
+// RUN: %clang_cc1 -std=c++23 -verify %s -DPLACEHOLDER="True decltype(auto)"
+
+// expected-no-diagnostics
+
+template<class T>
+concept True = true;
+
+namespace std {
+  template<class T>
+  constexpr PLACEHOLDER move(T&& t) noexcept {
+    return static_cast<__remove_reference_t(T)&&>(t);
+  }
+  constexpr PLACEHOLDER move_if_noexcept(auto& t) noexcept {
+    return static_cast<__remove_reference_t(decltype(t))&&>(t);
+  }
+  template<class T, class U>
+  constexpr PLACEHOLDER forward_like(U&& x) noexcept {
+    if constexpr (__is_const(__remove_reference_t(T))) {
+      using copy_const = const __remove_reference_t(U);
+      if constexpr (__is_rvalue_reference(T&&)) {
+        using V = __remove_reference_t(copy_const)&&;
+        return static_cast<V>(x);
+      } else {
+        using V = copy_const&;
+        return static_cast<V>(x);
+      }
+    } else {
+      using copy_const = __remove_reference_t(U);
+      if constexpr (__is_rvalue_reference(T&&)) {
+        using V = __remove_reference_t(copy_const)&&;
+        return static_cast<V>(x);
+      } else {
+        using V = copy_const&;
+        return static_cast<V>(x);
+      }
+    }
+  }
+}
+
+namespace GH101614 {
+int i;
+static_assert(__is_same(decltype(std::move(i)), int&&));
+static_assert(__is_same(decltype(std::move_if_noexcept(i)), int&&));
+static_assert(__is_same(decltype(std::forward_like<char>(i)), int&&));
+static_assert(__is_same(decltype(std::forward_like<char&>(i)), int&));
+
+constexpr bool is_i(int&& x) { return &x == &i; }
+void is_i(int&) = delete;
+void is_i(auto&&) = delete;
+
+static_assert(is_i(std::move(i)));
+static_assert(is_i(std::move_if_noexcept(i)));
+static_assert(is_i(std::forward_like<char>(i)));
+static_assert(&std::forward_like<char&>(i) == &i);
+
+// These types are incorrect, but make sure the types as declared are used
+static_assert(__is_same(decltype(std::move<int(&)()>), auto(int(&)()) noexcept 
-> int(&)()));
+static_assert(__is_same(decltype(std::move_if_noexcept<int(&)()>), 
auto(int(&)()) noexcept -> int(&)()));
+static_assert(__is_same(decltype(std::forward_like<int, int(&)()>), 
auto(int(&)()) noexcept -> int(&)()));
+} // namespace GH101614
diff --git a/clang/test/SemaCXX/builtin-std-move.cpp 
b/clang/test/SemaCXX/builtin-std-move.cpp
index a2ae21986308a..da85703c5d58e 100644
--- a/clang/test/SemaCXX/builtin-std-move.cpp
+++ b/clang/test/SemaCXX/builtin-std-move.cpp
@@ -172,3 +172,7 @@ namespace std {
   template<typename T> int &move(T);
 }
 int bad_signature = std::move(0); // expected-error {{unsupported signature 
for 'std::move<int>'}}
+
+namespace GH101690 {
+decltype(std::move_if_noexcept<int>)* p = nullptr;
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/101702
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to