From eb9da94d370efca51075a988c2c860a4e347158c Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Wed, 30 May 2007 00:06:37 +0000 Subject: [PATCH] Bug #: Submitted by: Reviewed by: Unified the diagnostics for function calls. Since we have range support, there is no need for including the argument number. Instead, I've made the diags more expressive by including more type info. Also improved the indentation of many calls to Diag (which can be 2-3 lines now). llvm-svn: 39523 --- clang/Sema/SemaExpr.cpp | 50 +++++++++---------- clang/include/clang/Basic/DiagnosticKinds.def | 6 +-- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/clang/Sema/SemaExpr.cpp b/clang/Sema/SemaExpr.cpp index d9136874c8b5..4693bc6234ed 100644 --- a/clang/Sema/SemaExpr.cpp +++ b/clang/Sema/SemaExpr.cpp @@ -22,7 +22,6 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringExtras.h" using namespace llvm; using namespace clang; @@ -364,15 +363,12 @@ ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc, ExprTy **Args, unsigned NumArgsInCall, SourceLocation *CommaLocs, SourceLocation RParenLoc) { Expr *funcExpr = (Expr *)Fn; - assert(funcExpr && "no function call expression"); QualType qType = funcExpr->getType(); - assert(!qType.isNull() && "no type for function call expression"); const FunctionType *funcT = dyn_cast(qType.getCanonicalType()); - assert(funcT && "ParseCallExpr(): not a function type"); // If a prototype isn't declared, the parser implicitly defines a func decl @@ -387,19 +383,18 @@ ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc, if (NumArgsInCall < NumArgsInProto) Diag(LParenLoc, diag::err_typecheck_call_too_few_args, - funcExpr->getSourceRange()); + funcExpr->getSourceRange()); else if (NumArgsInCall > NumArgsInProto) { if (!proto->isVariadic()) { Diag(LParenLoc, diag::err_typecheck_call_too_many_args, - funcExpr->getSourceRange(), - ((Expr **)Args)[NumArgsInProto]->getSourceRange()); + funcExpr->getSourceRange(), + ((Expr **)Args)[NumArgsInProto]->getSourceRange()); } NumArgsToCheck = NumArgsInProto; } // Continue to check argument types (even if we have too few/many args). for (unsigned i = 0; i < NumArgsToCheck; i++) { Expr *argExpr = ((Expr **)Args)[i]; - assert(argExpr && "ParseCallExpr(): missing argument expression"); QualType lhsType = proto->getArgType(i); @@ -413,29 +408,31 @@ ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc, SourceLocation l = argExpr->getLocStart(); // decode the result (notice that AST's are still created for extensions). - // FIXME: decide to include/exclude the argument # (decided to remove - // it for the incompatible diags below). The range should be sufficient. switch (result) { case Compatible: break; case PointerFromInt: // check for null pointer constant (C99 6.3.2.3p3) - if (!argExpr->isNullPointerConstant()) - Diag(l, diag::ext_typecheck_passing_pointer_from_int, utostr(i+1), - funcExpr->getSourceRange(), argExpr->getSourceRange()); + if (!argExpr->isNullPointerConstant()) { + Diag(l, diag::ext_typecheck_passing_pointer_from_int, + lhsType.getAsString(), + funcExpr->getSourceRange(), argExpr->getSourceRange()); + } break; case IntFromPointer: - Diag(l, diag::ext_typecheck_passing_int_from_pointer, utostr(i+1), - funcExpr->getSourceRange(), argExpr->getSourceRange()); + Diag(l, diag::ext_typecheck_passing_int_from_pointer, + rhsType.getAsString(), + funcExpr->getSourceRange(), argExpr->getSourceRange()); break; case IncompatiblePointer: Diag(l, diag::ext_typecheck_passing_incompatible_pointer, - rhsType.getAsString(), lhsType.getAsString(), - funcExpr->getSourceRange(), argExpr->getSourceRange()); + rhsType.getAsString(), lhsType.getAsString(), + funcExpr->getSourceRange(), argExpr->getSourceRange()); break; case CompatiblePointerDiscardsQualifiers: - Diag(l, diag::ext_typecheck_passing_discards_qualifiers, utostr(i+1), - funcExpr->getSourceRange(), argExpr->getSourceRange()); + Diag(l, diag::ext_typecheck_passing_discards_qualifiers, + rhsType.getAsString(), lhsType.getAsString(), + funcExpr->getSourceRange(), argExpr->getSourceRange()); break; case Incompatible: return Diag(l, diag::err_typecheck_passing_incompatible, @@ -524,8 +521,8 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15 if (!Type::typesAreCompatible(lhptee.getUnqualifiedType(), rhptee.getUnqualifiedType())) { Diag(questionLoc, diag::ext_typecheck_cond_incompatible_pointers, - lhs.getAsString(), rhs.getAsString(), - LHS->getSourceRange(), RHS->getSourceRange()); + lhs.getAsString(), rhs.getAsString(), + LHS->getSourceRange(), RHS->getSourceRange()); return lhs; // FIXME: this is an _ext - is this return o.k? } } @@ -533,8 +530,8 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15 return lhs; Diag(questionLoc, diag::err_typecheck_cond_incompatible_operands, - lhs.getAsString(), rhs.getAsString(), - LHS->getSourceRange(), RHS->getSourceRange()); + lhs.getAsString(), rhs.getAsString(), + LHS->getSourceRange(), RHS->getSourceRange()); return QualType(); } @@ -879,6 +876,7 @@ inline QualType Sema::CheckAssignmentOperands( // C99 6.5.16.1 QualType resType = UsualAssignmentConversions(lhsType, rhsType, result); // decode the result (notice that extensions still return a type). + // FIXME: make sure the text of the message is consistent with function calls. switch (result) { case Compatible: break; @@ -1016,17 +1014,17 @@ QualType Sema::CheckIndirectionOperand(Expr *op, SourceLocation OpLoc) { // GCC compat: special case 'void *' (treat as warning). if (ptype->isVoidType()) { Diag(OpLoc, diag::ext_typecheck_deref_ptr_to_void, - qType.getAsString(), op->getSourceRange()); + qType.getAsString(), op->getSourceRange()); } else { Diag(OpLoc, diag::err_typecheck_deref_incomplete_type, - ptype.getAsString(), op->getSourceRange()); + ptype.getAsString(), op->getSourceRange()); return QualType(); } } return ptype; } Diag(OpLoc, diag::err_typecheck_indirection_requires_pointer, - qType.getAsString(), op->getSourceRange()); + qType.getAsString(), op->getSourceRange()); return QualType(); } diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index e0931d195145..d5734da13b89 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -589,11 +589,11 @@ DIAG(err_typecheck_passing_incompatible, ERROR, DIAG(ext_typecheck_passing_incompatible_pointer, EXTENSION, "passing incompatible pointer '%0' to function expecting '%1'") DIAG(ext_typecheck_passing_int_from_pointer, EXTENSION, - "passing argument %0 makes integer from pointer without a cast") + "passing pointer '%0' to function expecting integer (without a cast)") DIAG(ext_typecheck_passing_pointer_from_int, EXTENSION, - "passing argument %0 makes pointer from integer without a cast") + "passing integer to function expecting '%0' (without a cast)") DIAG(ext_typecheck_passing_discards_qualifiers, EXTENSION, - "passing argument %0 discards qualifiers from pointer target type") + "function call discards qualifiers (passing '%0' to '%1')") DIAG(err_typecheck_cond_expect_scalar, ERROR, "used type '%0' where arithmetic or pointer type is required") DIAG(err_typecheck_cond_incompatible_operands, ERROR,