diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2011-02-18 23:54:50 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2011-02-18 23:54:50 +0000 |
commit | 82214a80c0163e01e4d8dec1426023c89277dbb4 (patch) | |
tree | a37aed12f142a232ee5d2b1d3a8f4ec5e409175c /lib/Sema/SemaExprCXX.cpp | |
parent | 0656e5b9aa52f2a90fb38517e504b4eebbe53381 (diff) |
Initial steps to improve diagnostics when there is a NULL and
a non-pointer on the two sides of a conditional expression.
Patch by Stephen Hines and Mihai Rusu.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125995 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 44508540d0..b78e52303e 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2874,13 +2874,14 @@ static bool TryClassUnification(Sema &Self, Expr *From, Expr *To, /// value operand is a class type, overload resolution is used to find a /// conversion to a common type. static bool FindConditionalOverload(Sema &Self, Expr *&LHS, Expr *&RHS, - SourceLocation Loc) { + SourceLocation QuestionLoc) { Expr *Args[2] = { LHS, RHS }; - OverloadCandidateSet CandidateSet(Loc); - Self.AddBuiltinOperatorCandidates(OO_Conditional, Loc, Args, 2, CandidateSet); + OverloadCandidateSet CandidateSet(QuestionLoc); + Self.AddBuiltinOperatorCandidates(OO_Conditional, QuestionLoc, Args, 2, + CandidateSet); OverloadCandidateSet::iterator Best; - switch (CandidateSet.BestViableFunction(Self, Loc, Best)) { + switch (CandidateSet.BestViableFunction(Self, QuestionLoc, Best)) { case OR_Success: // We found a match. Perform the conversions on the arguments and move on. if (Self.PerformImplicitConversion(LHS, Best->BuiltinTypes.ParamTypes[0], @@ -2891,13 +2892,20 @@ static bool FindConditionalOverload(Sema &Self, Expr *&LHS, Expr *&RHS, return false; case OR_No_Viable_Function: - Self.Diag(Loc, diag::err_typecheck_cond_incompatible_operands) + + // Emit a better diagnostic if one of the expressions is a null pointer + // constant and the other is a pointer type. In this case, the user most + // likely forgot to take the address of the other expression. + if (Self.DiagnoseConditionalForNull(LHS, RHS, QuestionLoc)) + return true; + + Self.Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands) << LHS->getType() << RHS->getType() << LHS->getSourceRange() << RHS->getSourceRange(); return true; case OR_Ambiguous: - Self.Diag(Loc, diag::err_conditional_ambiguous_ovl) + Self.Diag(QuestionLoc, diag::err_conditional_ambiguous_ovl) << LHS->getType() << RHS->getType() << LHS->getSourceRange() << RHS->getSourceRange(); // FIXME: Print the possible common types by printing the return types of |