diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-03-12 01:48:56 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-03-12 01:48:56 +0000 |
commit | fadb53b351977ca7f99a9a613596cba6531979a3 (patch) | |
tree | 62eb086a53b3804a617c98061b19b12fe45b911c /lib/Sema | |
parent | 5a5b38f4afaf4f203b96a11ba79890c7cd4cc4b8 (diff) |
Fixes for some more expressions containing function templateids that
should be resolvable, from Faisal Vali!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127521 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaCXXCast.cpp | 62 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 40 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 38 |
3 files changed, 83 insertions, 57 deletions
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index 5b28bc3d9f..557d27a943 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -128,17 +128,6 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *&SrcExpr, CastKind &Kind); -static ExprResult -ResolveAndFixSingleFunctionTemplateSpecialization( - Sema &Self, Expr *SrcExpr, - bool DoFunctionPointerConverion = false, - bool Complain = false, - const SourceRange& OpRangeForComplaining = SourceRange(), - QualType DestTypeForComplaining = QualType(), - unsigned DiagIDForComplaining = 0); - - - /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's. ExprResult Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, @@ -617,7 +606,7 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, Self.IgnoredValueConversions(SrcExpr); if (SrcExpr->getType() == Self.Context.OverloadTy) { ExprResult SingleFunctionExpression = - ResolveAndFixSingleFunctionTemplateSpecialization(Self, SrcExpr, + Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr, false, // Decay Function to ptr true, // Complain OpRange, DestType, diag::err_bad_static_cast_overload); @@ -1260,41 +1249,8 @@ static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType, return TC_Success; } -// A helper function to resolve and fix an overloaded expression that -// can be resolved because it identifies a single function -// template specialization -// Last three arguments should only be supplied if Complain = true -static ExprResult ResolveAndFixSingleFunctionTemplateSpecialization( - Sema &Self, Expr *SrcExpr, - bool DoFunctionPointerConverion, - bool Complain, - const SourceRange& OpRangeForComplaining, - QualType DestTypeForComplaining, - unsigned DiagIDForComplaining) { - assert(SrcExpr->getType() == Self.Context.OverloadTy); - DeclAccessPair Found; - Expr* SingleFunctionExpression = 0; - if (FunctionDecl* Fn = Self.ResolveSingleFunctionTemplateSpecialization( - SrcExpr, false, // false -> Complain - &Found)) { - if (!Self.DiagnoseUseOfDecl(Fn, SrcExpr->getSourceRange().getBegin())) { - // mark the expression as resolved to Fn - SingleFunctionExpression = Self.FixOverloadedFunctionReference(SrcExpr, - Found, Fn); - - if (DoFunctionPointerConverion) - Self.DefaultFunctionArrayLvalueConversion(SingleFunctionExpression); - } - } - if (!SingleFunctionExpression && Complain) { - OverloadExpr* oe = OverloadExpr::find(SrcExpr).Expression; - Self.Diag(OpRangeForComplaining.getBegin(), DiagIDForComplaining) - << oe->getName() << DestTypeForComplaining << OpRangeForComplaining - << oe->getQualifierLoc().getSourceRange(); - Self.NoteAllOverloadCandidates(SrcExpr); - } - return SingleFunctionExpression; -} + + static TryCastResult TryReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, bool CStyle, @@ -1311,7 +1267,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *&SrcExpr, if (SrcType == Self.Context.OverloadTy) { // ... unless foo<int> resolves to an lvalue unambiguously ExprResult SingleFunctionExpr = - ResolveAndFixSingleFunctionTemplateSpecialization(Self, SrcExpr, + Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr, Expr::getValueKindForType(DestType) == VK_RValue // Convert Fun to Ptr ); if (SingleFunctionExpr.isUsable()) { @@ -1544,11 +1500,11 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK, bool ret = false; // false is 'able to convert' if (CastExpr->getType() == Context.OverloadTy) { ExprResult SingleFunctionExpr = - ResolveAndFixSingleFunctionTemplateSpecialization(*this, - CastExpr, - /* Decay Function to ptr */ false, - /* Complain */ true, - R, CastTy, diag::err_bad_cstyle_cast_overload); + ResolveAndFixSingleFunctionTemplateSpecialization( + CastExpr, /* Decay Function to ptr */ false, + /* Complain */ true, R, CastTy, + diag::err_bad_cstyle_cast_overload); + if (SingleFunctionExpr.isUsable()) { CastExpr = SingleFunctionExpr.release(); Kind = CK_ToVoid; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 8a532f0363..546d2e7e38 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -5321,9 +5321,10 @@ bool Sema::DiagnoseConditionalForNull(Expr *LHS, Expr *RHS, QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, ExprValueKind &VK, ExprObjectKind &OK, SourceLocation QuestionLoc) { - // If both LHS and RHS are overloaded functions, try to resolve them. - if (Context.hasSameType(LHS->getType(), RHS->getType()) && - LHS->getType()->isSpecificBuiltinType(BuiltinType::Overload)) { + + // If either LHS or RHS are overloaded functions, try to resolve them. + if (LHS->getType() == Context.OverloadTy || + RHS->getType() == Context.OverloadTy) { ExprResult LHSResult = CheckPlaceholderExpr(LHS, QuestionLoc); if (LHSResult.isInvalid()) return QualType(); @@ -6313,6 +6314,10 @@ QualType Sema::InvalidOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) { Diag(Loc, diag::err_typecheck_invalid_operands) << lex->getType() << rex->getType() << lex->getSourceRange() << rex->getSourceRange(); + if (lex->getType() == Context.OverloadTy) + NoteAllOverloadCandidates(lex); + if (rex->getType() == Context.OverloadTy) + NoteAllOverloadCandidates(rex); return QualType(); } @@ -6789,12 +6794,14 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, QualType lType = lex->getType(); QualType rType = rex->getType(); - + Expr *LHSStripped = lex->IgnoreParenImpCasts(); Expr *RHSStripped = rex->IgnoreParenImpCasts(); QualType LHSStrippedType = LHSStripped->getType(); QualType RHSStrippedType = RHSStripped->getType(); + + // Two different enums will raise a warning when compared. if (const EnumType *LHSEnumType = LHSStrippedType->getAs<EnumType>()) { if (const EnumType *RHSEnumType = RHSStrippedType->getAs<EnumType>()) { @@ -8033,6 +8040,26 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, ExprValueKind VK = VK_RValue; ExprObjectKind OK = OK_Ordinary; + // Check if a 'foo<int>' involved in a binary op, identifies a single + // function unambiguously (i.e. an lvalue ala 13.4) + // But since an assignment can trigger target based overload, exclude it in + // our blind search. i.e: + // template<class T> void f(); template<class T, class U> void f(U); + // f<int> == 0; // resolve f<int> blindly + // void (*p)(int); p = f<int>; // resolve f<int> using target + if (Opc != BO_Assign) { + if (lhs->getType() == Context.OverloadTy) { + ExprResult resolvedLHS = + ResolveAndFixSingleFunctionTemplateSpecialization(lhs); + if (resolvedLHS.isUsable()) lhs = resolvedLHS.release(); + } + if (rhs->getType() == Context.OverloadTy) { + ExprResult resolvedRHS = + ResolveAndFixSingleFunctionTemplateSpecialization(rhs); + if (resolvedRHS.isUsable()) rhs = resolvedRHS.release(); + } + } + switch (Opc) { case BO_Assign: ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, QualType()); @@ -8390,6 +8417,11 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, resultType = CheckAddressOfOperand(*this, Input, OpLoc); break; case UO_Deref: + if (Input->getType() == Context.OverloadTy ) { + ExprResult er = ResolveAndFixSingleFunctionTemplateSpecialization(Input); + if (er.isUsable()) + Input = er.release(); + } DefaultFunctionArrayLvalueConversion(Input); resultType = CheckIndirectionOperand(*this, Input, VK, OpLoc); break; diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index bf24b74848..d746c7bb1e 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -7490,6 +7490,44 @@ FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(Expr *From, return Matched; } + + + +// Resolve and fix an overloaded expression that +// can be resolved because it identifies a single function +// template specialization +// Last three arguments should only be supplied if Complain = true +ExprResult Sema::ResolveAndFixSingleFunctionTemplateSpecialization( + Expr *SrcExpr, bool DoFunctionPointerConverion, bool Complain, + const SourceRange& OpRangeForComplaining, + QualType DestTypeForComplaining, + unsigned DiagIDForComplaining ) { + + assert(SrcExpr->getType() == Context.OverloadTy); + + DeclAccessPair Found; + Expr* SingleFunctionExpression = 0; + if (FunctionDecl* Fn = ResolveSingleFunctionTemplateSpecialization( + SrcExpr, false, // false -> Complain + &Found)) { + if (!DiagnoseUseOfDecl(Fn, SrcExpr->getSourceRange().getBegin())) { + // mark the expression as resolved to Fn + SingleFunctionExpression = FixOverloadedFunctionReference(SrcExpr, + Found, Fn); + if (DoFunctionPointerConverion) + DefaultFunctionArrayLvalueConversion(SingleFunctionExpression); + } + } + if (!SingleFunctionExpression && Complain) { + OverloadExpr* oe = OverloadExpr::find(SrcExpr).Expression; + Diag(OpRangeForComplaining.getBegin(), DiagIDForComplaining) + << oe->getName() << DestTypeForComplaining << OpRangeForComplaining + << oe->getQualifierLoc().getSourceRange(); + NoteAllOverloadCandidates(SrcExpr); + } + return SingleFunctionExpression; +} + /// \brief Add a single candidate to the overload set. static void AddOverloadedCallCandidate(Sema &S, DeclAccessPair FoundDecl, |