[clang] e75d8b7 - Revert "Treat `std::move`, `forward`, and `move_if_noexcept` as builtins."

Vitaly Buka via cfe-commits cfe-commits at lists.llvm.org
Sat Apr 16 00:29:26 PDT 2022


Author: Vitaly Buka
Date: 2022-04-16T00:27:51-07:00
New Revision: e75d8b70370435b0ad10388afba0df45fcf9bfcc

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

LOG: Revert "Treat `std::move`, `forward`, and `move_if_noexcept` as builtins."
Revert "Extend support for std::move etc to also cover std::as_const and"
Revert "Update test to handle opaque pointers flag flip."

It crashes on libcxx tests https://lab.llvm.org/buildbot/#/builders/85/builds/8174

This reverts commit fc3090109643af8d2da9822d0f99c84742b9c877.
This reverts commit a571f82a50416b767fd3cce0fb5027bb5dfec58c.
This reverts commit 64c045e25b8471bbb572bd29159c294a82a86a25.

Added: 
    

Modified: 
    clang/docs/CommandGuide/clang.rst
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/Builtins.def
    clang/include/clang/Basic/Builtins.h
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/AST/ExprConstant.cpp
    clang/lib/Analysis/BodyFarm.cpp
    clang/lib/Basic/Builtins.cpp
    clang/lib/CodeGen/CGBuiltin.cpp
    clang/lib/CodeGen/CGCall.cpp
    clang/lib/Sema/SemaChecking.cpp
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Sema/SemaExpr.cpp
    clang/lib/Sema/SemaExprCXX.cpp
    clang/lib/Sema/SemaInit.cpp
    clang/lib/Sema/SemaOverload.cpp
    clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    clang/test/Analysis/inner-pointer.cpp
    clang/test/Analysis/use-after-move.cpp
    clang/test/CodeGenCXX/builtins.cpp
    clang/test/CodeGenCXX/microsoft-abi-throw.cpp
    clang/test/SemaCXX/unqualified-std-call-fixits.cpp
    clang/test/SemaCXX/unqualified-std-call.cpp
    clang/test/SemaCXX/warn-consumed-analysis.cpp
    clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp

Removed: 
    clang/test/CodeGenCXX/builtin-std-move.cpp
    clang/test/SemaCXX/builtin-std-move-nobuiltin.cpp
    clang/test/SemaCXX/builtin-std-move.cpp


################################################################################
diff  --git a/clang/docs/CommandGuide/clang.rst b/clang/docs/CommandGuide/clang.rst
index 658a30458043e..aec62789a43e6 100644
--- a/clang/docs/CommandGuide/clang.rst
+++ b/clang/docs/CommandGuide/clang.rst
@@ -252,24 +252,8 @@ Language Selection and Mode Options
 
 .. option:: -fno-builtin
 
- Disable special handling and optimizations of well-known library functions,
- like :c:func:`strlen` and :c:func:`malloc`.
-
-.. option:: -fno-builtin-<function>
-
- Disable special handling and optimizations for the specific library function.
- For example, ``-fno-builtin-strlen`` removes any special handling for the
- :c:func:`strlen` library function.
-
-.. option:: -fno-builtin-std-<function>
-
- Disable special handling and optimizations for the specific C++ standard
- library function in namespace ``std``. For example,
- ``-fno-builtin-std-move_if_noexcept`` removes any special handling for the
- :cpp:func:`std::move_if_noexcept` library function.
-
- For C standard library functions that the C++ standard library also provides
- in namespace ``std``, use :option:`-fno-builtin-\<function\>` instead.
+ Disable special handling and optimizations of builtin functions like
+ :c:func:`strlen` and :c:func:`malloc`.
 
 .. option:: -fmath-errno
 

diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b2a5f6c366dd5..c72028c718586 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -230,10 +230,7 @@ C2x Feature Support
 C++ Language Changes in Clang
 -----------------------------
 
-- Improved ``-O0`` code generation for calls to ``std::move``, ``std::forward``,
-  and ``std::move_if_noexcept``. These are now treated as compiler builtins and
-  implemented directly, rather than instantiating the definition from the
-  standard library.
+- ...
 
 C++20 Feature Support
 ^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def
index c22957e14de7d..62e82cd36321d 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -81,9 +81,7 @@
 //       builtin even if type doesn't match signature, and don't warn if we
 //       can't be sure the type is right
 //  F -> this is a libc/libm function with a '__builtin_' prefix added.
-//  f -> this is a libc/libm function without a '__builtin_' prefix, or with
-//       'z', a C++ standard library function in namespace std::. This builtin
-//       is disableable by '-fno-builtin-foo' / '-fno-builtin-std-foo'.
+//  f -> this is a libc/libm function without the '__builtin_' prefix.
 //  h -> this function requires a specific header or an explicit declaration.
 //  i -> this is a runtime library implemented function without the
 //       '__builtin_' prefix. It will be implemented in compiler-rt or libgcc.
@@ -103,7 +101,6 @@
 //  V:N: -> requires vectors of at least N bits to be legal
 //  C<N,M_0,...,M_k> -> callback behavior: argument N is called with argument
 //                      M_0, ..., M_k as payload
-//  z -> this is a function in (possibly-versioned) namespace std
 //  FIXME: gcc has nonnull
 
 #if defined(BUILTIN) && !defined(LIBBUILTIN)
@@ -922,7 +919,7 @@ LANGBUILTIN(__exception_info, "v*",  "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(_exception_info,  "v*",  "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(__abnormal_termination, "i", "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(_abnormal_termination,  "i", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__GetExceptionInfo, "v*.", "zntu", ALL_MS_LANGUAGES)
+LANGBUILTIN(__GetExceptionInfo, "v*.", "ntu", ALL_MS_LANGUAGES)
 LANGBUILTIN(_InterlockedAnd8,   "ccD*c",        "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(_InterlockedAnd16,  "ssD*s",        "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(_InterlockedAnd,    "NiNiD*Ni",     "n", ALL_MS_LANGUAGES)
@@ -1546,15 +1543,6 @@ LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES)
 LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES)
 // FIXME: Also declare NSConcreteGlobalBlock and NSConcreteStackBlock.
 
-// C++ standard library builtins in namespace 'std'.
-LIBBUILTIN(addressof, "v*v&", "zfncTh", "memory", CXX_LANG)
-// Synonym for addressof used internally by libstdc++.
-LANGBUILTIN(__addressof, "v*v&", "zfncT", CXX_LANG)
-LIBBUILTIN(as_const, "v&v&", "zfncTh", "utility", CXX_LANG)
-LIBBUILTIN(forward, "v&v&", "zfncTh", "utility", CXX_LANG)
-LIBBUILTIN(move, "v&v&", "zfncTh", "utility", CXX_LANG)
-LIBBUILTIN(move_if_noexcept, "v&v&", "zfncTh", "utility", CXX_LANG)
-
 // Annotation function
 BUILTIN(__builtin_annotation, "v.", "tn")
 

diff  --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index a82e15730f992..2926e0fa2c8d6 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -138,10 +138,6 @@ class Context {
   /// Determines whether this builtin is a predefined libc/libm
   /// function, such as "malloc", where we know the signature a
   /// priori.
-  /// In C, such functions behave as if they are predeclared,
-  /// possibly with a warning on first use. In Objective-C and C++,
-  /// they do not, but they are recognized as builtins once we see
-  /// a declaration.
   bool isPredefinedLibFunction(unsigned ID) const {
     return strchr(getRecord(ID).Attributes, 'f') != nullptr;
   }
@@ -160,23 +156,6 @@ class Context {
     return strchr(getRecord(ID).Attributes, 'i') != nullptr;
   }
 
-  /// Determines whether this builtin is a C++ standard library function
-  /// that lives in (possibly-versioned) namespace std, possibly a template
-  /// specialization, where the signature is determined by the standard library
-  /// declaration.
-  bool isInStdNamespace(unsigned ID) const {
-    return strchr(getRecord(ID).Attributes, 'z') != nullptr;
-  }
-
-  /// Determines whether this builtin can have its address taken with no
-  /// special action required.
-  bool isDirectlyAddressable(unsigned ID) const {
-    // Most standard library functions can have their addresses taken. C++
-    // standard library functions formally cannot in C++20 onwards, and when
-    // we allow it, we need to ensure we instantiate a definition.
-    return isPredefinedLibFunction(ID) && !isInStdNamespace(ID);
-  }
-
   /// Determines whether this builtin has custom typechecking.
   bool hasCustomTypechecking(unsigned ID) const {
     return strchr(getRecord(ID).Attributes, 't') != nullptr;
@@ -258,6 +237,10 @@ class Context {
 private:
   const Info &getRecord(unsigned ID) const;
 
+  /// Is this builtin supported according to the given language options?
+  bool builtinIsSupported(const Builtin::Info &BuiltinInfo,
+                          const LangOptions &LangOpts);
+
   /// Helper function for isPrintfLike and isScanfLike.
   bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
               const char *Fmt) const;

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f71f576f9ff47..e79a40d62381f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6586,15 +6586,6 @@ def warn_self_move : Warning<
   "explicitly moving variable of type %0 to itself">,
   InGroup<SelfMove>, DefaultIgnore;
 
-def err_builtin_move_forward_unsupported : Error<
-  "unsupported signature for %q0">;
-def err_use_of_unaddressable_function : Error<
-  "taking address of non-addressable standard library function">;
-// FIXME: This should also be in -Wc++23-compat once we have it.
-def warn_cxx20_compat_use_of_unaddressable_function : Warning<
-  "taking address of non-addressable standard library function "
-  "is incompatible with C++20">, InGroup<CXX20Compat>;
-
 def warn_redundant_move_on_return : Warning<
   "redundant move in return statement">,
   InGroup<RedundantMove>, DefaultIgnore;

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 410fc8285bb65..6fe5d77a33fe5 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -8127,7 +8127,6 @@ class LValueExprEvaluator
   bool VisitVarDecl(const Expr *E, const VarDecl *VD);
   bool VisitUnaryPreIncDec(const UnaryOperator *UO);
 
-  bool VisitCallExpr(const CallExpr *E);
   bool VisitDeclRefExpr(const DeclRefExpr *E);
   bool VisitPredefinedExpr(const PredefinedExpr *E) { return Success(E); }
   bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E);
@@ -8293,20 +8292,6 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
   return Success(*V, E);
 }
 
-bool LValueExprEvaluator::VisitCallExpr(const CallExpr *E) {
-  switch (unsigned BuiltinOp = E->getBuiltinCallee()) {
-  case Builtin::BIas_const:
-  case Builtin::BIforward:
-  case Builtin::BImove:
-  case Builtin::BImove_if_noexcept:
-    if (cast<FunctionDecl>(E->getCalleeDecl())->isConstexpr())
-      return Visit(E->getArg(0));
-    break;
-  }
-
-  return ExprEvaluatorBaseTy::VisitCallExpr(E);
-}
-
 bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
     const MaterializeTemporaryExpr *E) {
   // Walk through the expression to find the materialized temporary itself.
@@ -9085,8 +9070,6 @@ static bool isOneByteCharacterType(QualType T) {
 bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
                                                 unsigned BuiltinOp) {
   switch (BuiltinOp) {
-  case Builtin::BIaddressof:
-  case Builtin::BI__addressof:
   case Builtin::BI__builtin_addressof:
     return evaluateLValue(E->getArg(0), Result);
   case Builtin::BI__builtin_assume_aligned: {

diff  --git a/clang/lib/Analysis/BodyFarm.cpp b/clang/lib/Analysis/BodyFarm.cpp
index 95bed548c567a..92c236ed9080c 100644
--- a/clang/lib/Analysis/BodyFarm.cpp
+++ b/clang/lib/Analysis/BodyFarm.cpp
@@ -20,7 +20,6 @@
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/Analysis/CodeInjector.h"
-#include "clang/Basic/Builtins.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/Debug.h"
@@ -87,9 +86,6 @@ class ASTMaker {
   ImplicitCastExpr *makeImplicitCast(const Expr *Arg, QualType Ty,
                                      CastKind CK = CK_LValueToRValue);
 
-  /// Create a cast to reference type.
-  CastExpr *makeReferenceCast(const Expr *Arg, QualType Ty);
-
   /// Create an Objective-C bool literal.
   ObjCBoolLiteralExpr *makeObjCBool(bool Val);
 
@@ -177,16 +173,6 @@ ImplicitCastExpr *ASTMaker::makeImplicitCast(const Expr *Arg, QualType Ty,
                                   /* FPFeatures */ FPOptionsOverride());
 }
 
-CastExpr *ASTMaker::makeReferenceCast(const Expr *Arg, QualType Ty) {
-  assert(Ty->isReferenceType());
-  return CXXStaticCastExpr::Create(
-      C, Ty.getNonReferenceType(),
-      Ty->isLValueReferenceType() ? VK_LValue : VK_XValue, CK_NoOp,
-      const_cast<Expr *>(Arg), /*CXXCastPath=*/nullptr,
-      /*Written=*/C.getTrivialTypeSourceInfo(Ty), FPOptionsOverride(),
-      SourceLocation(), SourceLocation(), SourceRange());
-}
-
 Expr *ASTMaker::makeIntegralCast(const Expr *Arg, QualType Ty) {
   if (Arg->getType() == Ty)
     return const_cast<Expr*>(Arg);
@@ -310,22 +296,6 @@ static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M,
       /*FPFeatures=*/FPOptionsOverride());
 }
 
-/// Create a fake body for 'std::move' or 'std::forward'. This is just:
-///
-/// \code
-/// return static_cast<return_type>(param);
-/// \endcode
-static Stmt *create_std_move_forward(ASTContext &C, const FunctionDecl *D) {
-  LLVM_DEBUG(llvm::dbgs() << "Generating body for std::move / std::forward\n");
-
-  ASTMaker M(C);
-
-  QualType ReturnType = D->getType()->castAs<FunctionType>()->getReturnType();
-  Expr *Param = M.makeDeclRefExpr(D->getParamDecl(0));
-  Expr *Cast = M.makeReferenceCast(Param, ReturnType);
-  return M.makeReturn(Cast);
-}
-
 /// Create a fake body for std::call_once.
 /// Emulates the following function body:
 ///
@@ -711,20 +681,8 @@ Stmt *BodyFarm::getBody(const FunctionDecl *D) {
 
   FunctionFarmer FF;
 
-  if (unsigned BuiltinID = D->getBuiltinID()) {
-    switch (BuiltinID) {
-    case Builtin::BIas_const:
-    case Builtin::BIforward:
-    case Builtin::BImove:
-    case Builtin::BImove_if_noexcept:
-      FF = create_std_move_forward;
-      break;
-    default:
-      FF = nullptr;
-      break;
-    }
-  } else if (Name.startswith("OSAtomicCompareAndSwap") ||
-             Name.startswith("objc_atomicCompareAndSwap")) {
+  if (Name.startswith("OSAtomicCompareAndSwap") ||
+      Name.startswith("objc_atomicCompareAndSwap")) {
     FF = create_OSAtomicCompareAndSwap;
   } else if (Name == "call_once" && D->getDeclContext()->isStdNamespace()) {
     FF = create_call_once;

diff  --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp
index ef8bb562ac17e..6d278e9c4a229 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -48,22 +48,18 @@ void Builtin::Context::InitializeTarget(const TargetInfo &Target,
 }
 
 bool Builtin::Context::isBuiltinFunc(llvm::StringRef FuncName) {
-  bool InStdNamespace = FuncName.consume_front("std-");
-  for (unsigned i = Builtin::NotBuiltin + 1; i != Builtin::FirstTSBuiltin;
-       ++i) {
-    if (FuncName.equals(BuiltinInfo[i].Name) &&
-        (bool)strchr(BuiltinInfo[i].Attributes, 'z') == InStdNamespace)
+  for (unsigned i = Builtin::NotBuiltin + 1; i != Builtin::FirstTSBuiltin; ++i)
+    if (FuncName.equals(BuiltinInfo[i].Name))
       return strchr(BuiltinInfo[i].Attributes, 'f') != nullptr;
-  }
 
   return false;
 }
 
-/// Is this builtin supported according to the given language options?
-static bool builtinIsSupported(const Builtin::Info &BuiltinInfo,
-                               const LangOptions &LangOpts) {
+bool Builtin::Context::builtinIsSupported(const Builtin::Info &BuiltinInfo,
+                                          const LangOptions &LangOpts) {
   bool BuiltinsUnsupported =
-      LangOpts.NoBuiltin && strchr(BuiltinInfo.Attributes, 'f') != nullptr;
+      (LangOpts.NoBuiltin || LangOpts.isNoBuiltinFunc(BuiltinInfo.Name)) &&
+      strchr(BuiltinInfo.Attributes, 'f');
   bool CorBuiltinsUnsupported =
       !LangOpts.Coroutines && (BuiltinInfo.Langs & COR_LANG);
   bool MathBuiltinsUnsupported =
@@ -115,19 +111,6 @@ void Builtin::Context::initializeBuiltins(IdentifierTable &Table,
   for (unsigned i = 0, e = AuxTSRecords.size(); i != e; ++i)
     Table.get(AuxTSRecords[i].Name)
         .setBuiltinID(i + Builtin::FirstTSBuiltin + TSRecords.size());
-
-  // Step #4: Unregister any builtins specified by -fno-builtin-foo.
-  for (llvm::StringRef Name : LangOpts.NoBuiltinFuncs) {
-    bool InStdNamespace = Name.consume_front("std-");
-    auto NameIt = Table.find(Name);
-    if (NameIt != Table.end()) {
-      unsigned ID = NameIt->second->getBuiltinID();
-      if (ID != Builtin::NotBuiltin && isPredefinedLibFunction(ID) &&
-          isInStdNamespace(ID) == InStdNamespace) {
-        Table.get(Name).setBuiltinID(Builtin::NotBuiltin);
-      }
-    }
-  }
 }
 
 unsigned Builtin::Context::getRequiredVectorWidth(unsigned ID) const {
@@ -207,7 +190,8 @@ bool Builtin::Context::performsCallback(unsigned ID,
 }
 
 bool Builtin::Context::canBeRedeclared(unsigned ID) const {
-  return ID == Builtin::NotBuiltin || ID == Builtin::BI__va_start ||
-         (!hasReferenceArgsOrResult(ID) && !hasCustomTypechecking(ID)) ||
-         isInStdNamespace(ID);
+  return ID == Builtin::NotBuiltin ||
+         ID == Builtin::BI__va_start ||
+         (!hasReferenceArgsOrResult(ID) &&
+          !hasCustomTypechecking(ID));
 }

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 640879f92493e..3adabcbf4bc97 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4566,8 +4566,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
 
     return RValue::get(Carry);
   }
-  case Builtin::BIaddressof:
-  case Builtin::BI__addressof:
   case Builtin::BI__builtin_addressof:
     return RValue::get(EmitLValue(E->getArg(0)).getPointer(*this));
   case Builtin::BI__builtin_function_start:
@@ -4727,12 +4725,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
     }
     break;
 
-  // C++ std:: builtins.
-  case Builtin::BImove:
-  case Builtin::BImove_if_noexcept:
-  case Builtin::BIforward:
-  case Builtin::BIas_const:
-    return RValue::get(EmitLValue(E->getArg(0)).getPointer(*this));
   case Builtin::BI__GetExceptionInfo: {
     if (llvm::GlobalVariable *GV =
             CGM.getCXXABI().getThrowInfo(FD->getParamDecl(0)->getType()))

diff  --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index d69455d650f43..e6a5fd1f4f985 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1805,8 +1805,6 @@ void CodeGenModule::getDefaultFunctionAttributes(StringRef Name,
 
   if (AttrOnCallSite) {
     // Attributes that should go on the call site only.
-    // FIXME: Look for 'BuiltinAttr' on the function rather than re-checking
-    // the -fno-builtin-foo list.
     if (!CodeGenOpts.SimplifyLibCalls || LangOpts.isNoBuiltinFunc(Name))
       FuncAttrs.addAttribute(llvm::Attribute::NoBuiltin);
     if (!CodeGenOpts.TrapFuncName.empty())

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index cd069d5664571..03f9b692c0631 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2130,32 +2130,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
 
     TheCall->setType(Context.VoidPtrTy);
     break;
-  case Builtin::BIaddressof:
-  case Builtin::BI__addressof:
-  case Builtin::BIforward:
-  case Builtin::BImove:
-  case Builtin::BImove_if_noexcept:
-  case Builtin::BIas_const: {
-    // These are all expected to be of the form
-    //   T &/&&/* f(U &/&&)
-    // where T and U only 
diff er in qualification.
-    if (checkArgCount(*this, TheCall, 1))
-      return ExprError();
-    QualType Param = FDecl->getParamDecl(0)->getType();
-    QualType Result = FDecl->getReturnType();
-    bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
-                          BuiltinID == Builtin::BI__addressof;
-    if (!(Param->isReferenceType() &&
-          (ReturnsPointer ? Result->isPointerType()
-                          : Result->isReferenceType()) &&
-          Context.hasSameUnqualifiedType(Param->getPointeeType(),
-                                         Result->getPointeeType()))) {
-      Diag(TheCall->getBeginLoc(), diag::err_builtin_move_forward_unsupported)
-          << FDecl;
-      return ExprError();
-    }
-    break;
-  }
   // OpenCL v2.0, s6.13.16 - Pipe functions
   case Builtin::BIread_pipe:
   case Builtin::BIwrite_pipe:

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 937478416f6d7..499c70e087898 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9269,32 +9269,6 @@ static Scope *getTagInjectionScope(Scope *S, const LangOptions &LangOpts) {
   return S;
 }
 
-/// Determine whether a declaration matches a known function in namespace std.
-static bool isStdBuiltin(ASTContext &Ctx, FunctionDecl *FD,
-                         unsigned BuiltinID) {
-  switch (BuiltinID) {
-  case Builtin::BI__GetExceptionInfo:
-    // No type checking whatsoever.
-    return Ctx.getTargetInfo().getCXXABI().isMicrosoft();
-
-  case Builtin::BIaddressof:
-  case Builtin::BI__addressof:
-  case Builtin::BIforward:
-  case Builtin::BImove:
-  case Builtin::BImove_if_noexcept:
-  case Builtin::BIas_const: {
-    // Ensure that we don't treat the algorithm
-    //   OutputIt std::move(InputIt, InputIt, OutputIt)
-    // as the builtin std::move.
-    const auto *FPT = FD->getType()->castAs<FunctionProtoType>();
-    return FPT->getNumParams() == 1 && !FPT->isVariadic();
-  }
-
-  default:
-    return false;
-  }
-}
-
 NamedDecl*
 Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
                               TypeSourceInfo *TInfo, LookupResult &Previous,
@@ -10147,30 +10121,28 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
 
   // If this is the first declaration of a library builtin function, add
   // attributes as appropriate.
-  if (!D.isRedeclaration()) {
+  if (!D.isRedeclaration() &&
+      NewFD->getDeclContext()->getRedeclContext()->isFileContext()) {
     if (IdentifierInfo *II = Previous.getLookupName().getAsIdentifierInfo()) {
       if (unsigned BuiltinID = II->getBuiltinID()) {
-        bool InStdNamespace = Context.BuiltinInfo.isInStdNamespace(BuiltinID);
-        if (!InStdNamespace &&
-            NewFD->getDeclContext()->getRedeclContext()->isFileContext()) {
-          if (NewFD->getLanguageLinkage() == CLanguageLinkage) {
-            // Validate the type matches unless this builtin is specified as
-            // matching regardless of its declared type.
-            if (Context.BuiltinInfo.allowTypeMismatch(BuiltinID)) {
+        if (NewFD->getLanguageLinkage() == CLanguageLinkage) {
+          // Validate the type matches unless this builtin is specified as
+          // matching regardless of its declared type.
+          if (Context.BuiltinInfo.allowTypeMismatch(BuiltinID)) {
+            NewFD->addAttr(BuiltinAttr::CreateImplicit(Context, BuiltinID));
+          } else {
+            ASTContext::GetBuiltinTypeError Error;
+            LookupNecessaryTypesForBuiltin(S, BuiltinID);
+            QualType BuiltinType = Context.GetBuiltinType(BuiltinID, Error);
+
+            if (!Error && !BuiltinType.isNull() &&
+                Context.hasSameFunctionTypeIgnoringExceptionSpec(
+                    NewFD->getType(), BuiltinType))
               NewFD->addAttr(BuiltinAttr::CreateImplicit(Context, BuiltinID));
-            } else {
-              ASTContext::GetBuiltinTypeError Error;
-              LookupNecessaryTypesForBuiltin(S, BuiltinID);
-              QualType BuiltinType = Context.GetBuiltinType(BuiltinID, Error);
-
-              if (!Error && !BuiltinType.isNull() &&
-                  Context.hasSameFunctionTypeIgnoringExceptionSpec(
-                      NewFD->getType(), BuiltinType))
-                NewFD->addAttr(BuiltinAttr::CreateImplicit(Context, BuiltinID));
-            }
           }
-        } else if (InStdNamespace && NewFD->isInStdNamespace() &&
-                   isStdBuiltin(Context, NewFD, BuiltinID)) {
+        } else if (BuiltinID == Builtin::BI__GetExceptionInfo &&
+                   Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+          // FIXME: We should consider this a builtin only in the std namespace.
           NewFD->addAttr(BuiltinAttr::CreateImplicit(Context, BuiltinID));
         }
       }

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index cfebd3cb928cf..334ece62c2bea 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3395,7 +3395,7 @@ ExprResult Sema::BuildDeclarationNameExpr(
 
   case Decl::Function: {
     if (unsigned BID = cast<FunctionDecl>(VD)->getBuiltinID()) {
-      if (!Context.BuiltinInfo.isDirectlyAddressable(BID)) {
+      if (!Context.BuiltinInfo.isPredefinedLibFunction(BID)) {
         type = Context.BuiltinFnTy;
         valueKind = VK_PRValue;
         break;
@@ -20528,8 +20528,7 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
     auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts());
     if (DRE) {
       auto *FD = cast<FunctionDecl>(DRE->getDecl());
-      unsigned BuiltinID = FD->getBuiltinID();
-      if (BuiltinID == Builtin::BI__noop) {
+      if (FD->getBuiltinID() == Builtin::BI__noop) {
         E = ImpCastExprToType(E, Context.getPointerType(FD->getType()),
                               CK_BuiltinFnToFnPtr)
                 .get();
@@ -20537,36 +20536,6 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
                                 VK_PRValue, SourceLocation(),
                                 FPOptionsOverride());
       }
-
-      if (Context.BuiltinInfo.isInStdNamespace(BuiltinID)) {
-        // Any use of these other than a direct call is ill-formed as of C++20,
-        // because they are not addressable functions. In earlier language
-        // modes, warn and force an instantiation of the real body.
-        Diag(E->getBeginLoc(),
-             getLangOpts().CPlusPlus20
-                 ? diag::err_use_of_unaddressable_function
-                 : diag::warn_cxx20_compat_use_of_unaddressable_function);
-        if (FD->isImplicitlyInstantiable()) {
-          // Require a definition here because a normal attempt at
-          // instantiation for a builtin will be ignored, and we won't try
-          // again later. We assume that the definition of the template
-          // precedes this use.
-          InstantiateFunctionDefinition(E->getBeginLoc(), FD,
-                                        /*Recursive=*/false,
-                                        /*DefinitionRequired=*/true,
-                                        /*AtEndOfTU=*/false);
-        }
-        // Produce a properly-typed reference to the function.
-        CXXScopeSpec SS;
-        SS.Adopt(DRE->getQualifierLoc());
-        TemplateArgumentListInfo TemplateArgs;
-        DRE->copyTemplateArgumentsInto(TemplateArgs);
-        return BuildDeclRefExpr(
-            FD, FD->getType(), VK_LValue, DRE->getNameInfo(),
-            DRE->hasQualifier() ? &SS : nullptr, DRE->getFoundDecl(),
-            DRE->getTemplateKeywordLoc(),
-            DRE->hasExplicitTemplateArgs() ? &TemplateArgs : nullptr);
-      }
     }
 
     Diag(E->getBeginLoc(), diag::err_builtin_fn_use);

diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index e765d1ff9760d..aad9574e9e694 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -4236,14 +4236,6 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
       return ExprError();
 
     From = FixOverloadedFunctionReference(From, Found, Fn);
-
-    // We might get back another placeholder expression if we resolved to a
-    // builtin.
-    ExprResult Checked = CheckPlaceholderExpr(From);
-    if (Checked.isInvalid())
-      return ExprError();
-
-    From = Checked.get();
     FromType = From->getType();
   }
 

diff  --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index f76fd92d09d3b..233be547bf118 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -8215,10 +8215,6 @@ ExprResult InitializationSequence::Perform(Sema &S,
       CurInit = S.FixOverloadedFunctionReference(CurInit,
                                                  Step->Function.FoundDecl,
                                                  Step->Function.Function);
-      // We might get back another placeholder expression if we resolved to a
-      // builtin.
-      if (!CurInit.isInvalid())
-        CurInit = S.CheckPlaceholderExpr(CurInit.get());
       break;
 
     case SK_CastDerivedToBasePRValue:

diff  --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 1add971a81a02..33271609a0081 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1747,6 +1747,13 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
                "Non-address-of operator for overloaded function expression");
         FromType = S.Context.getPointerType(FromType);
       }
+
+      // Check that we've computed the proper type after overload resolution.
+      // FIXME: FixOverloadedFunctionReference has side-effects; we shouldn't
+      // be calling it from within an NDEBUG block.
+      assert(S.Context.hasSameType(
+        FromType,
+        S.FixOverloadedFunctionReference(From, AccessPair, Fn)->getType()));
     } else {
       return false;
     }
@@ -15181,9 +15188,10 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
     if (SubExpr == UnOp->getSubExpr())
       return UnOp;
 
-    // FIXME: This can't currently fail, but in principle it could.
-    return CreateBuiltinUnaryOp(UnOp->getOperatorLoc(), UO_AddrOf, SubExpr)
-        .get();
+    return UnaryOperator::Create(
+        Context, SubExpr, UO_AddrOf, Context.getPointerType(SubExpr->getType()),
+        VK_PRValue, OK_Ordinary, UnOp->getOperatorLoc(), false,
+        CurFPFeatureOverrides());
   }
 
   if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
@@ -15194,20 +15202,10 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
       TemplateArgs = &TemplateArgsBuffer;
     }
 
-    QualType Type = Fn->getType();
-    ExprValueKind ValueKind = getLangOpts().CPlusPlus ? VK_LValue : VK_PRValue;
-
-    // FIXME: Duplicated from BuildDeclarationNameExpr.
-    if (unsigned BID = Fn->getBuiltinID()) {
-      if (!Context.BuiltinInfo.isDirectlyAddressable(BID)) {
-        Type = Context.BuiltinFnTy;
-        ValueKind = VK_PRValue;
-      }
-    }
-
-    DeclRefExpr *DRE = BuildDeclRefExpr(
-        Fn, Type, ValueKind, ULE->getNameInfo(), ULE->getQualifierLoc(),
-        Found.getDecl(), ULE->getTemplateKeywordLoc(), TemplateArgs);
+    DeclRefExpr *DRE =
+        BuildDeclRefExpr(Fn, Fn->getType(), VK_LValue, ULE->getNameInfo(),
+                         ULE->getQualifierLoc(), Found.getDecl(),
+                         ULE->getTemplateKeywordLoc(), TemplateArgs);
     DRE->setHadMultipleCandidates(ULE->getNumDecls() > 1);
     return DRE;
   }

diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 8b0147fc66c36..9d0dc8cad46b8 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4771,12 +4771,6 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
   if (TSK == TSK_ExplicitSpecialization)
     return;
 
-  // Never implicitly instantiate a builtin; we don't actually need a function
-  // body.
-  if (Function->getBuiltinID() && TSK == TSK_ImplicitInstantiation &&
-      !DefinitionRequired)
-    return;
-
   // Don't instantiate a definition if we already have one.
   const FunctionDecl *ExistingDefn = nullptr;
   if (Function->isDefined(ExistingDefn,

diff  --git a/clang/test/Analysis/inner-pointer.cpp b/clang/test/Analysis/inner-pointer.cpp
index 5db17a952f90b..920a1fe8dcc9d 100644
--- a/clang/test/Analysis/inner-pointer.cpp
+++ b/clang/test/Analysis/inner-pointer.cpp
@@ -379,7 +379,7 @@ void func_addressof() {
   const char *c;
   std::string s;
   c = s.c_str();
-  (void)addressof(s);
+  addressof(s);
   consume(c); // no-warning
 }
 

diff  --git a/clang/test/Analysis/use-after-move.cpp b/clang/test/Analysis/use-after-move.cpp
index ce9b26f15360e..d1278cad4c4f2 100644
--- a/clang/test/Analysis/use-after-move.cpp
+++ b/clang/test/Analysis/use-after-move.cpp
@@ -244,7 +244,7 @@ void reinitializationTest(int i) {
     A a;
     if (i == 1) { // peaceful-note 2 {{'i' is not equal to 1}}
                   // peaceful-note at -1 2 {{Taking false branch}}
-      (void)std::move(a);
+      std::move(a);
     }
     if (i == 2) { // peaceful-note 2 {{'i' is not equal to 2}}
                   // peaceful-note at -1 2 {{Taking false branch}}
@@ -494,7 +494,7 @@ void templateArgIsNotUseTest() {
 // Moves of global variables are not reported.
 A global_a;
 void globalVariablesTest() {
-  (void)std::move(global_a);
+  std::move(global_a);
   global_a.foo(); // no-warning
 }
 

diff  --git a/clang/test/CodeGenCXX/builtin-std-move.cpp b/clang/test/CodeGenCXX/builtin-std-move.cpp
deleted file mode 100644
index 9df4beea72bec..0000000000000
--- a/clang/test/CodeGenCXX/builtin-std-move.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -o - -std=c++17 %s | FileCheck %s --implicit-check-not=@_ZSt4move
-
-namespace std {
-  template<typename T> constexpr T &&move(T &val) { return static_cast<T&&>(val); }
-  template<typename T> constexpr T &&move_if_noexcept(T &val);
-  template<typename T> constexpr T &&forward(T &val);
-  template<typename T> constexpr const T &as_const(T &val);
-
-  // Not the builtin.
-  template<typename T, typename U> T move(U source, U source_end, T dest);
-}
-
-class T {};
-extern "C" void take(T &&);
-extern "C" void take_lval(const T &);
-
-T a;
-
-// Check emission of a constant-evaluated call.
-// CHECK-DAG: @move_a = constant ptr @a
-T &&move_a = std::move(a);
-// CHECK-DAG: @move_if_noexcept_a = constant ptr @a
-T &&move_if_noexcept_a = std::move_if_noexcept(a);
-// CHECK-DAG: @forward_a = constant ptr @a
-T &forward_a = std::forward<T&>(a);
-
-// Check emission of a non-constant call.
-// CHECK-LABEL: define {{.*}} void @test
-extern "C" void test(T &t) {
-  // CHECK: store ptr %{{.*}}, ptr %[[T_REF:[^,]*]]
-  // CHECK: %0 = load ptr, ptr %[[T_REF]]
-  // CHECK: call void @take(ptr {{.*}} %0)
-  take(std::move(t));
-  // CHECK: %1 = load ptr, ptr %[[T_REF]]
-  // CHECK: call void @take(ptr {{.*}} %1)
-  take(std::move_if_noexcept(t));
-  // CHECK: %2 = load ptr, ptr %[[T_REF]]
-  // CHECK: call void @take(ptr {{.*}} %2)
-  take(std::forward<T&&>(t));
-  // CHECK: %3 = load ptr, ptr %[[T_REF]]
-  // CHECK: call void @take_lval(ptr {{.*}} %3)
-  take_lval(std::as_const<T&&>(t));
-
-  // CHECK: call {{.*}} @_ZSt4moveI1TS0_ET_T0_S2_S1_
-  std::move(t, t, t);
-}
-
-// CHECK: declare {{.*}} @_ZSt4moveI1TS0_ET_T0_S2_S1_
-
-// Check that we instantiate and emit if the address is taken.
-// CHECK-LABEL: define {{.*}} @use_address
-extern "C" void *use_address() {
-  // CHECK: ret {{.*}} @_ZSt4moveIiEOT_RS0_
-  return (void*)&std::move<int>;
-}
-
-// CHECK: define {{.*}} ptr @_ZSt4moveIiEOT_RS0_(ptr

diff  --git a/clang/test/CodeGenCXX/builtins.cpp b/clang/test/CodeGenCXX/builtins.cpp
index 56a29eac2490c..c1c8b51cbae6d 100644
--- a/clang/test/CodeGenCXX/builtins.cpp
+++ b/clang/test/CodeGenCXX/builtins.cpp
@@ -30,24 +30,6 @@ S *addressof(bool b, S &s, S &t) {
   return __builtin_addressof(b ? s : t);
 }
 
-namespace std { template<typename T> T *addressof(T &); }
-
-// CHECK: define {{.*}} @_Z13std_addressofbR1SS0_(
-S *std_addressof(bool b, S &s, S &t) {
-  // CHECK: %[[LVALUE:.*]] = phi
-  // CHECK: ret {{.*}}* %[[LVALUE]]
-  return std::addressof(b ? s : t);
-}
-
-namespace std { template<typename T> T *__addressof(T &); }
-
-// CHECK: define {{.*}} @_Z15std___addressofbR1SS0_(
-S *std___addressof(bool b, S &s, S &t) {
-  // CHECK: %[[LVALUE:.*]] = phi
-  // CHECK: ret {{.*}}* %[[LVALUE]]
-  return std::__addressof(b ? s : t);
-}
-
 extern "C" int __builtin_abs(int); // #1
 long __builtin_abs(long);          // #2
 extern "C" int __builtin_abs(int); // #3

diff  --git a/clang/test/CodeGenCXX/microsoft-abi-throw.cpp b/clang/test/CodeGenCXX/microsoft-abi-throw.cpp
index aa79935e42ded..92849598cf063 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-throw.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-throw.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -o - -triple=i386-pc-win32 -std=c++11 %s -fcxx-exceptions -fms-extensions | FileCheck %s
+// RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -o - -triple=i386-pc-win32 -std=c++11 %s -fcxx-exceptions -fms-extensions -DSTD | FileCheck %s
 
 // CHECK-DAG: @"??_R0?AUY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUY@@\00" }, comdat
 // CHECK-DAG: @"_CT??_R0?AUY@@@8??0Y@@QAE at ABU0@@Z8" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 4, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUY@@@8" to i8*), i32 0, i32 -1, i32 0, i32 8, i8* bitcast (%struct.Y* (%struct.Y*, %struct.Y*, i32)* @"??0Y@@QAE at ABU0@@Z" to i8*) }, section ".xdata", comdat
@@ -133,10 +134,15 @@ void h() {
   throw nullptr;
 }
 
+#ifdef STD
 namespace std {
 template <typename T>
 void *__GetExceptionInfo(T);
 }
+#else
+template <typename T>
+void *__GetExceptionInfo(T);
+#endif
 using namespace std;
 
 void *GetExceptionInfo_test0() {

diff  --git a/clang/test/SemaCXX/builtin-std-move-nobuiltin.cpp b/clang/test/SemaCXX/builtin-std-move-nobuiltin.cpp
deleted file mode 100644
index 9185bd87bf8ab..0000000000000
--- a/clang/test/SemaCXX/builtin-std-move-nobuiltin.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: %clang_cc1 -std=c++20 -verify %s -DBUILTIN=builtin
-// RUN: %clang_cc1 -std=c++20 -verify %s -DBUILTIN=nobuiltin -fno-builtin
-// RUN: %clang_cc1 -std=c++20 -verify %s -DBUILTIN=nobuiltin -fno-builtin-std-move -fno-builtin-std-move_if_noexcept -fno-builtin-std-forward
-// RUN: %clang_cc1 -std=c++20 -verify %s -DBUILTIN=nobuiltin -ffreestanding
-// expected-no-diagnostics
-
-int nobuiltin;
-
-namespace std {
-  template<typename T> constexpr T &&move(T &x) { return (T&&)nobuiltin; }
-  template<typename T> constexpr T &&move_if_noexcept(T &x) { return (T&&)nobuiltin; }
-  template<typename T> constexpr T &&forward(T &x) { return (T&&)nobuiltin; }
-}
-
-template<typename T> constexpr T *addr(T &&r) { return &r; }
-
-int builtin;
-static_assert(addr(std::move(builtin)) == &BUILTIN);
-static_assert(addr(std::move_if_noexcept(builtin)) == &BUILTIN);
-static_assert(addr(std::forward(builtin)) == &BUILTIN);

diff  --git a/clang/test/SemaCXX/builtin-std-move.cpp b/clang/test/SemaCXX/builtin-std-move.cpp
deleted file mode 100644
index a53e57c86c14c..0000000000000
--- a/clang/test/SemaCXX/builtin-std-move.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-// RUN: %clang_cc1 -std=c++17 -verify %s
-// RUN: %clang_cc1 -std=c++17 -verify %s -DNO_CONSTEXPR
-// RUN: %clang_cc1 -std=c++20 -verify %s
-
-namespace std {
-#ifndef NO_CONSTEXPR
-#define CONSTEXPR constexpr
-#else
-#define CONSTEXPR
-#endif
-
-  template<typename T> CONSTEXPR T &&move(T &x) {
-    static_assert(T::moveable, "instantiated move"); // expected-error {{no member named 'moveable' in 'B'}}
-                                                     // expected-error at -1 {{no member named 'moveable' in 'C'}}
-    return static_cast<T&&>(x);
-  }
-
-  // Unrelated move functions are not the builtin.
-  template<typename T> CONSTEXPR int move(T, T) { return 5; }
-
-  template<typename T, bool Rref> struct ref { using type = T&; };
-  template<typename T> struct ref<T, true> { using type = T&&; };
-
-  template<typename T> CONSTEXPR auto move_if_noexcept(T &x) -> typename ref<T, noexcept(T(static_cast<T&&>(x)))>::type {
-    static_assert(T::moveable, "instantiated move_if_noexcept"); // expected-error {{no member named 'moveable' in 'B'}}
-    return static_cast<typename ref<T, noexcept(T(static_cast<T&&>(x)))>::type>(x);
-  }
-
-  template<typename T> struct remove_reference { using type = T; };
-  template<typename T> struct remove_reference<T&> { using type = T; };
-  template<typename T> struct remove_reference<T&&> { using type = T; };
-
-  template<typename T> CONSTEXPR T &&forward(typename remove_reference<T>::type &x) {
-    static_assert(T::moveable, "instantiated forward"); // expected-error {{no member named 'moveable' in 'B'}}
-                                                        // expected-error at -1 {{no member named 'moveable' in 'C'}}
-    return static_cast<T&&>(x);
-  }
-
-  template<typename T> CONSTEXPR const T &as_const(T &x) {
-    static_assert(T::moveable, "instantiated as_const"); // expected-error {{no member named 'moveable' in 'B'}}
-    return x;
-  }
-
-  template<typename T> CONSTEXPR T *addressof(T &x) {
-    static_assert(T::moveable, "instantiated addressof"); // expected-error {{no member named 'moveable' in 'B'}}
-    return __builtin_addressof(x);
-  }
-
-  template<typename T> CONSTEXPR T *__addressof(T &x) {
-    static_assert(T::moveable, "instantiated __addressof"); // expected-error {{no member named 'moveable' in 'B'}}
-    return __builtin_addressof(x);
-  }
-}
-
-// Note: this doesn't have a 'moveable' member. Instantiation of the above
-// functions will fail if it's attempted.
-struct A {};
-constexpr bool f(A a) { // #f
-  A &&move = std::move(a); // #call
-  A &&move_if_noexcept = std::move_if_noexcept(a);
-  A &&forward1 = std::forward<A>(a);
-  A &forward2 = std::forward<A&>(a);
-  const A &as_const = std::as_const(a);
-  A *addressof = std::addressof(a);
-  A *addressof2 = std::__addressof(a);
-  return &move == &a && &move_if_noexcept == &a &&
-         &forward1 == &a && &forward2 == &a &&
-         &as_const == &a && addressof == &a &&
-         addressof2 == &a && std::move(a, a) == 5;
-}
-
-#ifndef NO_CONSTEXPR
-static_assert(f({}), "should be constexpr");
-#else
-// expected-error@#f {{never produces a constant expression}}
-// expected-note@#call {{}}
-#endif
-
-struct B {};
-B &&(*pMove)(B&) = std::move; // #1 expected-note {{instantiation of}}
-B &&(*pMoveIfNoexcept)(B&) = &std::move_if_noexcept; // #2 expected-note {{instantiation of}}
-B &&(*pForward)(B&) = &std::forward<B>; // #3 expected-note {{instantiation of}}
-const B &(*pAsConst)(B&) = &std::as_const; // #4 expected-note {{instantiation of}}
-B *(*pAddressof)(B&) = &std::addressof; // #5 expected-note {{instantiation of}}
-B *(*pUnderUnderAddressof)(B&) = &std::__addressof; // #6 expected-note {{instantiation of}}
-int (*pUnrelatedMove)(B, B) = std::move;
-
-struct C {};
-C &&(&rMove)(C&) = std::move; // #7 expected-note {{instantiation of}}
-C &&(&rForward)(C&) = std::forward<C>; // #8 expected-note {{instantiation of}}
-int (&rUnrelatedMove)(B, B) = std::move;
-
-#if __cplusplus <= 201703L
-// expected-warning@#1 {{non-addressable}}
-// expected-warning@#2 {{non-addressable}}
-// expected-warning@#3 {{non-addressable}}
-// expected-warning@#4 {{non-addressable}}
-// expected-warning@#5 {{non-addressable}}
-// expected-warning@#6 {{non-addressable}}
-// expected-warning@#7 {{non-addressable}}
-// expected-warning@#8 {{non-addressable}}
-#else
-// expected-error@#1 {{non-addressable}}
-// expected-error@#2 {{non-addressable}}
-// expected-error@#3 {{non-addressable}}
-// expected-error@#4 {{non-addressable}}
-// expected-error@#5 {{non-addressable}}
-// expected-error@#6 {{non-addressable}}
-// expected-error@#7 {{non-addressable}}
-// expected-error@#8 {{non-addressable}}
-#endif
-
-void attribute_const() {
-  int n;
-  std::move(n); // expected-warning {{ignoring return value}}
-  std::move_if_noexcept(n); // expected-warning {{ignoring return value}}
-  std::forward<int>(n); // expected-warning {{ignoring return value}}
-  std::addressof(n); // expected-warning {{ignoring return value}}
-  std::__addressof(n); // expected-warning {{ignoring return value}}
-  std::as_const(n); // expected-warning {{ignoring return value}}
-}
-
-namespace std {
-  template<typename T> int move(T);
-}
-int bad_signature = std::move(0); // expected-error {{unsupported signature for 'std::move<int>'}}

diff  --git a/clang/test/SemaCXX/unqualified-std-call-fixits.cpp b/clang/test/SemaCXX/unqualified-std-call-fixits.cpp
index d6f8e5e2b95ed..0b2d70c0360a3 100644
--- a/clang/test/SemaCXX/unqualified-std-call-fixits.cpp
+++ b/clang/test/SemaCXX/unqualified-std-call-fixits.cpp
@@ -6,9 +6,9 @@
 
 namespace std {
 
-int &&move(auto &&a) { return a; }
+void move(auto &&a) {}
 
-int &&forward(auto &a) { return a; }
+void forward(auto &a) {}
 
 } // namespace std
 
@@ -16,8 +16,8 @@ using namespace std;
 
 void f() {
   int i = 0;
-  (void)move(i); // expected-warning {{unqualified call to std::move}}
-  // CHECK: {{^}}  (void)std::move
-  (void)forward(i); // expected-warning {{unqualified call to std::forward}}
-  // CHECK: {{^}}  (void)std::forward
+  move(i); // expected-warning {{unqualified call to std::move}}
+  // CHECK: {{^}}  std::
+  forward(i); // expected-warning {{unqualified call to std::forward}}
+              // CHECK: {{^}}  std::
 }

diff  --git a/clang/test/SemaCXX/unqualified-std-call.cpp b/clang/test/SemaCXX/unqualified-std-call.cpp
index 0c78c26d063a9..fa66ae9f8e321 100644
--- a/clang/test/SemaCXX/unqualified-std-call.cpp
+++ b/clang/test/SemaCXX/unqualified-std-call.cpp
@@ -1,17 +1,17 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wall -std=c++11 %s -Wno-unused-value
+// RUN: %clang_cc1 -fsyntax-only -verify -Wall -std=c++11 %s
 
 namespace std {
 
 template <typename T>
 void dummy(T &&) {}
 template <typename T>
-T &&move(T &&x) { return x; }
+void move(T &&) {}
 template <typename T, typename U>
 void move(T &&, U &&) {}
 
 inline namespace __1 {
 template <typename T>
-T &forward(T &x) { return x; }
+void forward(T &) {}
 } // namespace __1
 
 struct foo {};

diff  --git a/clang/test/SemaCXX/warn-consumed-analysis.cpp b/clang/test/SemaCXX/warn-consumed-analysis.cpp
index 8e09779e64404..b4dddb6763724 100644
--- a/clang/test/SemaCXX/warn-consumed-analysis.cpp
+++ b/clang/test/SemaCXX/warn-consumed-analysis.cpp
@@ -953,12 +953,12 @@ void test6() {
 namespace std {
   void move();
   template<class T>
-  T &&move(T&);
+  void move(T&&);
 
   namespace __1 {
     void move();
     template<class T>
-    T &&move(T&);
+    void move(T&&);
   }
 }
 
@@ -971,7 +971,7 @@ namespace PR18260 {
   void test() {
     x.move();
     std::move();
-    std::move(x); // expected-warning {{ignoring return value}}
+    std::move(x);
     std::__1::move();
     std::__1::move(x);
   }

diff  --git a/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp b/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
index e6360d88a893d..a4410d330d393 100644
--- a/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
+++ b/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
@@ -1444,7 +1444,7 @@ TEST(ExprMutationAnalyzerTest, UnevaluatedContext) {
 TEST(ExprMutationAnalyzerTest, ReproduceFailureMinimal) {
   const std::string Reproducer =
       "namespace std {"
-      "template <class T> T &forward(T &A) { return static_cast<T&&>(A); }"
+      "template <class T> T forward(T & A) { return static_cast<T&&>(A); }"
       "template <class T> struct __bind {"
       "  T f;"
       "  template <class V> __bind(T v, V &&) : f(forward(v)) {}"


        


More information about the cfe-commits mailing list