CPP-Aware C++ Rewriting Can Be Fun

Recently MCPP started working well enough to process all of Mozilla with the special macro-expansion undoing markup. Below is the most exciting patch line I have produced so far. A few months ago, I didn’t think was possible to rewrite macro parameters with elsa.

- ENCODE_SIMPLE_ARRAY(PRBool, Bool, (PRUint16) values[i]);
+ ENCODE_SIMPLE_ARRAY(PRBool, Bool, 0 != ((PRUint16) values[i]));

To produce this:

  1. Elsa consumed the expanded .ii file
  2. Boolean checker found the problematic subexpression
  3. Original source position was calculated from the expansion log
  4. Then prcheck figured out that only the macro parameter needs to be rewritten.
  5. Original source was read in and enclosed within 0 != ()

Integrating Static Checks – PRBool check

This bug contains the rest of the rewriting results. Prcheck checks every assignment to a prbool and outputs a patch if the expression may evaluate to anything other than 0/1. A message is produced if a patch can not be generated because the expression is within a macro.

The goal is to have prcheck run on every commit(or every day) and send out an email or another form of a complaint when a new prbool violation is introduced. Since the current prbool misuses aren’t going to be fixed overnight, there should be a db kept somewhere with the old misuses to prevent the new ones from being introduced and old ones from being annoying. I’m thinking of associating misuse counts with a filename, so when the number goes up an error gets mailed out. Anyone get a better idea?

Latest Recipe to Running Oink Tools

  1. If you want to rewrite sources either wait for the next mcpp release or use my tarball.
  2. Install gcc 3.4.x. If using mcpp, configure mcpp with –enable-replace-system so it replaces the gcc preprocessor
  3. Checkout and build my oink version.
  4. Build mozilla with -save-temps gcc option. If using mcpp set environment variables CC=”gcc -Wp,-K -Wp,-W0 -save-temps ” and CXX=”g++ -Wp,-K -Wp,-W0 -save-temps ” and do make -f client.mk build as usual. The extra gcc parameters tell it to save intermediate files to pass -K and -W0 to enable macro expansion annotation and silence warnings.
  5. Run tools individual files
  6. Produce a global patch with ./pork-barrel 4 /path/to/prcheck /tmp/input.txt where input.txt is a list of absolute filenames of all of the .i and .ii files produced by the build process

3 comments

  1. You could call cvs annotate on the file, and locate the line(s) where problems occur. That will give you the committer and the revision. if the revision is >’n’ then email the committer (And perhaps CC: a list somewhere) with the complaint(s), and if it’s

  2. Robert O'Callahan

    That’s awesome!

  3. If I introduce badness in a macro in a header file, will I get email for every place it’s used? If so, it seems like you really want to run after each check-in and send a single e-mail to the committer if that specific check-in increased any of the counts.

    (If it sounds expensive: you can optimize away most of the runs. Just run once a day to see if any counts have increased. If they haven’t, you can skip running for every check-in that occurred that day.)