Qt-QStringArg

Check suspicious arg calls of QString and QLatin1String

Required inputs: IR

Implements three warnings:
  1. Detects when you are using chained QString::arg() calls and should instead use the multi-arg overload to save memory allocations
    QString("%1 %2").arg(a).arg(b);
    QString("%1 %2").arg(a, b); // one less temporary heap allocation
    
  2. Detects when you are passing an integer to QLatin1String::arg() as that gets implicitly cast to QChar. It's preferable to state your intention and cast to QChar explicitly.
  3. Detects when you are using misleading QString::arg() overloads
    QString arg(qlonglong a, int fieldwidth = 0, int base = 10, QChar fillChar = QLatin1Char(' ')) const
    QString arg(qulonglong a, int fieldwidth = 0, int base = 10, QChar fillChar = QLatin1Char(' ')) const
    QString arg(long a, int fieldwidth = 0, int base=10, QChar fillChar = QLatin1Char(' ')) const
    QString arg(ulong a, int fieldwidth = 0, int base=10, QChar fillChar = QLatin1Char(' ')) const
    QString arg(int a, int fieldWidth = 0, int base = 10, QChar fillChar = QLatin1Char(' ')) const
    QString arg(uint a, int fieldWidth = 0, int base = 10, QChar fillChar = QLatin1Char(' ')) const
    QString arg(short a, int fieldWidth = 0, int base = 10, QChar fillChar = QLatin1Char(' ')) const
    QString arg(ushort a, int fieldWidth = 0, int base = 10, QChar fillChar = QLatin1Char(' ')) const
    QString arg(double a, int fieldWidth = 0, char fmt = 'g', int prec = -1, QChar fillChar = QLatin1Char(' ')) const
    QString arg(char a, int fieldWidth = 0, QChar fillChar = QLatin1Char(' ')) const
    QString arg(QChar a, int fieldWidth = 0, QChar fillChar = QLatin1Char(' ')) const
    QString arg(const QString &a, int fieldWidth = 0, QChar fillChar = QLatin1Char(' ')) const
    
    because they are commonly misused, for example:
    int hours = ...;
    int minutes = ...;
    // This will not do what you think it would at first glance.
    QString s("The time is %1:%2").arg(hours, minutes);
    
    To reduce false positives, some cases will not be warned about:
    str.arg(hours, 2); // User explicitly used a integer literal, this is probably fine
    str.arg(foo); // We are only after cases where the second argument (or further) is specified, so this is safe
    str.arg(foo, width); // Second argument is named width, or contains the name "width" or "count", this is safe.
    

    Using these misleading overloads may be perfectly valid but can be replaced by QString::asprintf. The message key misleading_qstring_arg may be disabled.

    The name to match the second argument may be configured by changing the option width_argument_name.

This rule is based on clazy rule qstring-arg

Possible Messages

Key

Text

Severity

Disabled

chained_arg_calls

Use multi-arg instead of chained arg calls.

None

False

implicit_qlatin1_cast

Argument passed to QLatin1String::arg() will be implicitly cast to QChar.

None

False

misleading_qstring_arg

QString::arg() used with fillChar overload.

None

False

Options

level

level : int = 0

Importance level of the rule as given for clazy. 0 is most desirable, higher values fall off in quality.
 

width_argument_name

width_argument_name : str = '.*(width|count).*'

If this case-insensitive regexp matches the name of the second argument of a misleading overload then the call is considered safe and not reported.