[cfe-dev] clang printf correspondence between conversion specifier and arguments

Ted Kremenek kremenek at apple.com
Wed Jan 20 22:24:07 PST 2010


Hi Cristi,

This is definitely on the right track.

To add a warning, you only need to modify the TableGen files (.td), as the .inc files are generated from the .td files during the build.  Specifically, you only need to modify DiagnosticSemaKinds.td and add one warning to the Format group.  Your warning declaration would look something like:

 def my_warning : Warning<
  "conversion specifies type '%0' but the argument has type '%1'">, InGroup<Format>;

You would then use it similarly to the warn_printf_asterisk_precision_wrong_type warning (in SemaChecking.cpp), except you specify two QualType arguments instead of one.

Please also include a couple test cases that show when the warning is both reported and *not* reported.  The test cases should also include the use of typedefs (which I believe your logic already handles).

- Ted

On Jan 19, 2010, at 11:26 PM, Cristian Draghici wrote:

> Hi
> 
> I've started looking at printf correspondence between conversion specifier and arguments.
> 
> 1/ Am I on the right track with the patch below?
> 
> 2/ Assuming an affirmative answer on (1), I'm not sure how to define a new warning (I used warn_printf_asterisk_width_wrong_type which is wrong in this case).
> I'm guessing defs are in include/clang/Basic/DiagnosticSemaKinds.inc and .td and referred in DiagnosticGroups.inc and .td
> A new diagnostic would be needed, along the lines of "conversion specifies type 'X', but argument has type 'Y'"
> 
> 
> Thanks for your time,
> Cristi
> 
> 
> cristi:clang diciu$ svn diff  ./lib/Sema/SemaChecking.cpp
> Index: lib/Sema/SemaChecking.cpp
> ===================================================================
> --- lib/Sema/SemaChecking.cpp	(revision 93981)
> +++ lib/Sema/SemaChecking.cpp	(working copy)
> @@ -1147,7 +1147,17 @@
>      //
>      // FIXME: additional checks will go into the following cases.
>      case 'i':
> -    case 'd':
> +    case 'd': {
> +      if(numDataArgs >= format_idx+numConversions+1) {
> +        const Expr *E2 = TheCall->getArg(format_idx+numConversions+1);
> +        const BuiltinType *BT = E2->getType()->getAs<BuiltinType>();
> +        if(BT == NULL || BT->getKind() != BuiltinType::Int) {
> +          SourceLocation Loc = getLocationOfStringLiteralByte(FExpr, StrIdx);
> +          Diag(Loc, diag::warn_printf_asterisk_width_wrong_type)
> +            << E2->getType() << E2->getSourceRange();
> +        }
> +      }
> +    }
>      case 'o':
>      case 'u':
>      case 'x':
> 
> 
> 
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev





More information about the cfe-dev mailing list