aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-03-12 01:48:56 +0000
committerDouglas Gregor <dgregor@apple.com>2011-03-12 01:48:56 +0000
commitfadb53b351977ca7f99a9a613596cba6531979a3 (patch)
tree62eb086a53b3804a617c98061b19b12fe45b911c /lib/Sema/SemaExpr.cpp
parent5a5b38f4afaf4f203b96a11ba79890c7cd4cc4b8 (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/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp40
1 files changed, 36 insertions, 4 deletions
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;