diff --git a/clang/docs/CommandGuide/clang.rst b/clang/docs/CommandGuide/clang.rst index 658a30458043..aec62789a43e 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- - - 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- - - 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-\` 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 cb5cad717e34..4e63effe5769 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -250,10 +250,7 @@ C2x Feature Support C++ Language Changes in Clang ----------------------------- -- Improved ``-O0`` code generation for calls to ``std::move``, ``std::forward``, - ``std::move_if_noexcept``, ``std::addressof``, and ``std::as_const``. 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 c22957e14de7..62e82cd36321 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 -> 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 a82e15730f99..2926e0fa2c8d 100644 --- a/clang/include/clang/Basic/Builtins.h +++ b/clang/include/clang/Basic/Builtins.h @@ -138,10 +138,6 @@ public: /// 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 @@ public: 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 @@ public: 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 26e6db82a47f..2008f02bf990 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6590,15 +6590,6 @@ def warn_self_move : Warning< "explicitly moving variable of type %0 to itself">, InGroup, 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; - def warn_redundant_move_on_return : Warning< "redundant move in return statement">, InGroup, DefaultIgnore; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 3ad44d5e2da8..6fe5d77a33fe 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -8127,7 +8127,6 @@ public: 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 (E->getBuiltinCallee()) { - case Builtin::BIas_const: - case Builtin::BIforward: - case Builtin::BImove: - case Builtin::BImove_if_noexcept: - if (cast(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 95bed548c567..92c236ed9080 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 @@ public: 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(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(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(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()->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 ef8bb562ac17..6d278e9c4a22 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 fc2d32f3e26f..17adc9ba7507 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2271,9 +2271,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, ReturnValueSlot ReturnValue) { const FunctionDecl *FD = GD.getDecl()->getAsFunction(); // See if we can constant fold this builtin. If so, don't emit it at all. - // TODO: Extend this handling to all builtin calls that we can constant-fold. Expr::EvalResult Result; - if (E->isPRValue() && E->EvaluateAsRValue(Result, CGM.getContext()) && + if (E->EvaluateAsRValue(Result, CGM.getContext()) && !Result.hasSideEffects()) { if (Result.Val.isInt()) return RValue::get(llvm::ConstantInt::get(getLLVMContext(), @@ -4567,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: @@ -4728,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 d69455d650f4..e6a5fd1f4f98 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 467edd3321b9..34de3df7a80c 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 differ 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 0c8b7fcd306b..30164e56120c 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -9276,32 +9276,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(); - return FPT->getNumParams() == 1 && !FPT->isVariadic(); - } - - default: - return false; - } -} - NamedDecl* Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo, LookupResult &Previous, @@ -10154,30 +10128,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)) { - NewFD->addAttr(BuiltinAttr::CreateImplicit(Context, BuiltinID)); - } else { - ASTContext::GetBuiltinTypeError Error; - LookupNecessaryTypesForBuiltin(S, BuiltinID); - QualType BuiltinType = Context.GetBuiltinType(BuiltinID, Error); + 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)); - } + 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 3bd83b813686..273de0867e3e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3396,7 +3396,7 @@ ExprResult Sema::BuildDeclarationNameExpr( case Decl::Function: { if (unsigned BID = cast(VD)->getBuiltinID()) { - if (!Context.BuiltinInfo.isDirectlyAddressable(BID)) { + if (!Context.BuiltinInfo.isPredefinedLibFunction(BID)) { type = Context.BuiltinFnTy; valueKind = VK_PRValue; break; @@ -20480,8 +20480,7 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { auto *DRE = dyn_cast(E->IgnoreParenImpCasts()); if (DRE) { auto *FD = cast(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(); @@ -20489,36 +20488,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 7b3a18a50381..79b670a1ec73 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4237,14 +4237,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 2a49627ecf10..c7048225c9d4 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 1add971a81a0..33271609a008 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(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 8b0147fc66c3..9d0dc8cad46b 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 5db17a952f90..920a1fe8dcc9 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 ce9b26f15360..d1278cad4c4f 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@-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@-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 55a96dac4c57..000000000000 --- a/clang/test/CodeGenCXX/builtin-std-move.cpp +++ /dev/null @@ -1,66 +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 constexpr T &&move(T &val) { return static_cast(val); } - template constexpr T &&move_if_noexcept(T &val); - template constexpr T &&forward(T &val); - template constexpr const T &as_const(T &val); - - // Not the builtin. - template 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(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)); - // CHECK: %3 = load ptr, ptr %[[T_REF]] - // CHECK: call void @take_lval(ptr {{.*}} %3) - take_lval(std::as_const(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; -} - -// CHECK: define {{.*}} ptr @_ZSt4moveIiEOT_RS0_(ptr - -extern "C" void take_const_int_rref(const int &&); -// CHECK-LABEL: define {{.*}} @move_const_int( -extern "C" void move_const_int() { - // CHECK: store i32 5, ptr %[[N_ADDR:[^,]*]] - const int n = 5; - // CHECK: call {{.*}} @take_const_int_rref(ptr {{.*}} %[[N_ADDR]]) - take_const_int_rref(std::move(n)); -} diff --git a/clang/test/CodeGenCXX/builtins.cpp b/clang/test/CodeGenCXX/builtins.cpp index 56a29eac2490..c1c8b51cbae6 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 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 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 aa79935e42de..92849598cf06 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@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@ABU0@@Z" to i8*) }, section ".xdata", comdat @@ -133,10 +134,15 @@ void h() { throw nullptr; } +#ifdef STD namespace std { template void *__GetExceptionInfo(T); } +#else +template +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 9185bd87bf8a..000000000000 --- 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 constexpr T &&move(T &x) { return (T&&)nobuiltin; } - template constexpr T &&move_if_noexcept(T &x) { return (T&&)nobuiltin; } - template constexpr T &&forward(T &x) { return (T&&)nobuiltin; } -} - -template 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 a53e57c86c14..000000000000 --- 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 CONSTEXPR T &&move(T &x) { - static_assert(T::moveable, "instantiated move"); // expected-error {{no member named 'moveable' in 'B'}} - // expected-error@-1 {{no member named 'moveable' in 'C'}} - return static_cast(x); - } - - // Unrelated move functions are not the builtin. - template CONSTEXPR int move(T, T) { return 5; } - - template struct ref { using type = T&; }; - template struct ref { using type = T&&; }; - - template CONSTEXPR auto move_if_noexcept(T &x) -> typename ref(x)))>::type { - static_assert(T::moveable, "instantiated move_if_noexcept"); // expected-error {{no member named 'moveable' in 'B'}} - return static_cast(x)))>::type>(x); - } - - template struct remove_reference { using type = T; }; - template struct remove_reference { using type = T; }; - template struct remove_reference { using type = T; }; - - template CONSTEXPR T &&forward(typename remove_reference::type &x) { - static_assert(T::moveable, "instantiated forward"); // expected-error {{no member named 'moveable' in 'B'}} - // expected-error@-1 {{no member named 'moveable' in 'C'}} - return static_cast(x); - } - - template 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 CONSTEXPR T *addressof(T &x) { - static_assert(T::moveable, "instantiated addressof"); // expected-error {{no member named 'moveable' in 'B'}} - return __builtin_addressof(x); - } - - template 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 &forward2 = std::forward(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; // #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; // #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(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 int move(T); -} -int bad_signature = std::move(0); // expected-error {{unsupported signature for 'std::move'}} diff --git a/clang/test/SemaCXX/unqualified-std-call-fixits.cpp b/clang/test/SemaCXX/unqualified-std-call-fixits.cpp index d6f8e5e2b95e..0b2d70c0360a 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 0c78c26d063a..fa66ae9f8e32 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 void dummy(T &&) {} template -T &&move(T &&x) { return x; } +void move(T &&) {} template void move(T &&, U &&) {} inline namespace __1 { template -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 8e09779e6440..b4dddb676372 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 - T &&move(T&); + void move(T&&); namespace __1 { void move(); template - 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 e6360d88a893..a4410d330d39 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 T &forward(T &A) { return static_cast(A); }" + "template T forward(T & A) { return static_cast(A); }" "template struct __bind {" " T f;" " template __bind(T v, V &&) : f(forward(v)) {}"