Analyzer question

Hello,

I would like to write static analyses checks for Qt, specifically for the meta-object usage. Qt uses some pre-processor macros which are used by the meta-object compiler (moc) to generate extra code. For example:

class MyObject: public QObject {
  Q_OBJECT // expands to a field declaration and some utility methods

signals: // expands to protected
  void somethingChanged();

public slots: // expands to Q_SLOTS which expands to empty
  void changeSomething();
};

I checked the IBAction/IBOutlet macros, but it looks like they expand to __attribute__((ibaction)) (or iboutlet) when using code completion, and to void/empty when compiling -- meaning: while running the analyzer, they do not end up in the AST.

So, what would be the best way to do it for Qt? If I understand the pre-processing correctly, I would need to do two passes while analysing, or I would need to annotate methods with an additional flag (akin to the ibaction/iboutlet flags) while parsing. I think that annotating while parsing is the most solid way, as one could also use it while doing code-completion or code-navigation.

What do you think? And would such a change/patch be allowed into the clang source tree?

Regards,
Erik Verbruggen.

Hello,

I would like to write static analyses checks for Qt, specifically for the meta-object usage. Qt uses some pre-processor macros which are used by the meta-object compiler (moc) to generate extra code. For example:

class MyObject: public QObject {
  Q_OBJECT // expands to a field declaration and some utility methods

signals: // expands to protected
  void somethingChanged();

public slots: // expands to Q_SLOTS which expands to empty
  void changeSomething();
};

I checked the IBAction/IBOutlet macros, but it looks like they expand to __attribute__((ibaction)) (or iboutlet) when using code completion, and to void/empty when compiling -- meaning: while running the analyzer, they do not end up in the AST.

Hi Erik,

When doing analysis, we actually do expand IBOutlet/IBAction to these attributes (it depends on what version of scan-build/Xcode you are using).

So, what would be the best way to do it for Qt? If I understand the pre-processing correctly, I would need to do two passes while analysing,

I'm not certain why you would need two passes. The parser always sees preprocessed code.

or I would need to annotate methods with an additional flag (akin to the ibaction/iboutlet flags) while parsing. I think that annotating while parsing is the most solid way, as one could also use it while doing code-completion or code-navigation.

I think if you can have your macros expand to something that include semantic breadcrumbs (e.g., attributes) that you can use for your analysis, then that is the way to go. Besides introducing new attributes (e.g., "iboutlet"), the "annotate" attribute might be a useful swiss-army knife here. The question then comes down to how/when these macros are defined to include these attributes. If these macros are defined in the Qt headers, these changes can possibly be put there and be properly #ifdef'ed to include the "clang-specific" changes. Alternatively, we can possibly provide a mechanism for checkers to register macro definitions in the predefine buffers, or investigate other solutions.

What do you think? And would such a change/patch be allowed into the clang source tree?

I suspect that this can be done with the existing infrastructure without changes to Clang itself (other than the introduction of the checker, if you wanted to commit that back to Clang mainline). Whether or not this requires Clang changes really depends on the details of the solution (i.e., which attributes are used, when the macros are defined, and so forth).