VirtualBox

Changeset 56975 in vbox


Ignore:
Timestamp:
Jul 18, 2015 12:18:26 AM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
101687
Message:

gccplugin.cpp: a wee bit further.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bldprogs/gccplugin.cpp

    r56973 r56975  
    5454
    5555
    56 /** For use with messages. */
    57 #define MY_LOC(a_hPreferred, a_pState) \
    58     (DECL_P(a_hPreferred) ? DECL_SOURCE_LOCATION(a_hPreferred) : gimple_location((a_pState)->hStmt))
     56/** For use with messages.
     57 * @todo needs some more work... Actually, seems we're a bit handicapped by
     58 *       working on gimplified stuff. */
     59#define MY_LOC(a_hPreferred, a_pState) EXPR_LOC_OR_LOC(a_hPreferred, (a_pState)->hFmtLoc)
    5960
    6061
     
    6869    long        iFmt;
    6970    long        iArgs;
     71    location_t  hFmtLoc;
    7072} MYCHECKSTATE;
    7173/** Pointer to my checker state. */
     
    202204
    203205
    204 static void MyCheckFormatCString(PMYCHECKSTATE pState, const char *pszFmt, location_t hFmtLoc)
    205 {
    206     dprintf("checker2: \"%s\"\n", pszFmt);
     206#define MYSTATE_FMT_FILE(a_pState)      LOCATION_FILE((a_pState)->hFmtLoc)
     207#define MYSTATE_FMT_LINE(a_pState)      LOCATION_LINE((a_pState)->hFmtLoc)
     208#define MYSTATE_FMT_COLUMN(a_pState)    LOCATION_COLUMN((a_pState)->hFmtLoc)
     209
     210
     211/**
     212 * Checks that @a iFmtArg isn't present or a valid final dummy argument.
     213 *
     214 * Will issue warning/error if there are more arguments at @a iFmtArg.
     215 *
     216 * @param   pState              The format string checking state.
     217 * @param   iArg                The index of the end of arguments, this is
     218 *                              relative to MYCHECKSTATE::iArgs.
     219 */
     220void MyCheckFinalArg(PMYCHECKSTATE pState, unsigned iArg)
     221{
     222    dprintf("MyCheckFinalArg: iArg=%u iArgs=%ld cArgs=%u\n", iArg, pState->iArgs, gimple_call_num_args(pState->hStmt));
     223    if (pState->iArgs > 0)
     224    {
     225        iArg += pState->iArgs - 1;
     226        unsigned cArgs = gimple_call_num_args(pState->hStmt);
     227        if (iArg == cArgs)
     228        { /* fine */ }
     229        else if (iArg < cArgs)
     230        {
     231            tree hArg = gimple_call_arg(pState->hStmt, iArg);
     232            if (cArgs - iArg > 1)
     233                warning_at(MY_LOC(hArg, pState), 0, "%u extra arguments not consumed by format string", cArgs - iArg);
     234            else if (   TREE_CODE(hArg) != INTEGER_CST
     235                     || TREE_INT_CST(hArg).fits_shwi()
     236                     || TREE_INT_CST(hArg).to_shwi() != -99) /* ignore final dummy argument: ..., -99); */
     237                warning_at(MY_LOC(hArg, pState), 0, "one extra argument not consumed by format string");
     238        }
     239        /* This should be handled elsewhere, but just in case. */
     240        else if (iArg - 1 == cArgs)
     241            warning_at(pState->hFmtLoc, 0, "one argument too few");
     242        else
     243            warning_at(pState->hFmtLoc, 0, "%u arguments too few", iArg - cArgs);
     244    }
     245}
     246
     247
     248/**
     249 * Does the actual format string checking.
     250 *
     251 * @todo    Move this to different file common to both GCC and CLANG later.
     252 *
     253 * @param   pState              The format string checking state.
     254 * @param   pszFmt              The format string.
     255 */
     256void MyCheckFormatCString(PMYCHECKSTATE pState, const char *pszFmt)
     257{
     258    dprintf("checker2: \"%s\" at %s:%d col %d\n", pszFmt,
     259            MYSTATE_FMT_FILE(pState), MYSTATE_FMT_LINE(pState), MYSTATE_FMT_COLUMN(pState));
     260    unsigned iArg = 0;
     261    for (;;)
     262    {
     263        /*
     264         * Skip to the next argument.
     265         */
     266        char ch;
     267        while ((ch = *pszFmt++) != '%')
     268            if (ch == '\0')
     269            {
     270                MyCheckFinalArg(pState, iArg);
     271                return;
     272            }
     273
     274
     275    }
    207276}
    208277
     
    214283 * passes on to MyCheckFormatString for the actual analyzis.
    215284 *
    216  * @param   pState              The format string check state.
     285 * @param   pState              The format string checking state.
    217286 * @param   hFmtArg             The format string node.
    218287 */
    219 DECL_NO_INLINE(static, void) MyCheckFormatWorker(PMYCHECKSTATE pState, tree hFmtArg)
     288DECL_NO_INLINE(static, void) MyCheckFormatNonRecursive(PMYCHECKSTATE pState, tree hFmtArg)
    220289{
    221290    dprintf("checker: hFmtArg=%p %s\n", hFmtArg, tree_code_name[TREE_CODE(hFmtArg)]);
    222     location_t hFmtLoc = MY_LOC(hFmtArg, pState);
    223291
    224292    /*
     
    236304     */
    237305    if (integer_zerop(hFmtArg))
    238         warning_at(hFmtLoc, 0, "Format string should not be NULL");
     306        warning_at(MY_LOC(hFmtArg, pState), 0, "Format string should not be NULL");
    239307    /*
    240308     * Need address expression to get any further.
     
    244312    else
    245313    {
    246         hFmtLoc = EXPR_LOC_OR_LOC(hFmtArg, hFmtLoc);
     314        pState->hFmtLoc = EXPR_LOC_OR_LOC(hFmtArg, pState->hFmtLoc);
    247315        hFmtArg = TREE_OPERAND(hFmtArg, 0);
    248316
     
    287355            dprintf("checker1: Not string literal (%s)\n", tree_code_name[TREE_CODE(hFmtArg)]);
    288356        else if (TYPE_MAIN_VARIANT(TREE_TYPE(TREE_TYPE(hFmtArg))) != char_type_node)
    289             warning_at(hFmtLoc, 0, "expected 'char' type string literal");
     357            warning_at(pState->hFmtLoc, 0, "expected 'char' type string literal");
    290358        else
    291359        {
     
    300368            {
    301369                if (TREE_CODE(hArraySize) != INTEGER_CST)
    302                     warning_at(hFmtLoc, 0, "Expected integer array size (not %s)", tree_code_name[TREE_CODE(hArraySize)]);
     370                    warning_at(pState->hFmtLoc, 0, "Expected integer array size (not %s)", tree_code_name[TREE_CODE(hArraySize)]);
    303371                else if (!TREE_INT_CST(hArraySize).fits_shwi())
    304                     warning_at(hFmtLoc, 0, "Unexpected integer overflow in array size constant");
     372                    warning_at(pState->hFmtLoc, 0, "Unexpected integer overflow in array size constant");
    305373                else
    306374                {
     
    308376                    if (   cbArray <= 0
    309377                        || cbArray != (int)cbArray)
    310                         warning_at(hFmtLoc, 0, "Unexpected integer array size constant value: %ld", cbArray);
     378                        warning_at(pState->hFmtLoc, 0, "Unexpected integer array size constant value: %ld", cbArray);
    311379                    else if (cchFmt > cbArray)
    312380                    {
     
    334402            if (   cchFmt < 1
    335403                || pszFmt[cchFmt - 1] != '\0')
    336                 warning_at(hFmtLoc, 0, "Unterminated format string (cchFmt=%d)", cchFmt);
     404                warning_at(pState->hFmtLoc, 0, "Unterminated format string (cchFmt=%d)", cchFmt);
    337405            /*
    338406             * Call worker to check the actual string.
    339407             */
    340408            else
    341                 MyCheckFormatCString(pState, pszFmt, hFmtLoc);
     409                MyCheckFormatCString(pState, pszFmt);
    342410        }
    343411    }
     
    348416 * Deal recursively with special format string constructs.
    349417 *
    350  * This will call MyCheckFormatWorker to validate each format string.
    351  *
    352  * @param   pState              The format string check state.
     418 * This will call MyCheckFormatNonRecursive to validate each format string.
     419 *
     420 * @param   pState              The format string checking state.
    353421 * @param   hFmtArg             The format string node.
    354422 */
     
    378446     */
    379447    else
    380         MyCheckFormatWorker(pState, hFmtArg);
     448        MyCheckFormatNonRecursive(pState, hFmtArg);
    381449}
    382450
     
    443511                    tree const hAttrArgs = TREE_VALUE(hAttr);
    444512                    MYCHECKSTATE State;
    445                     State.iFmt  = TREE_INT_CST(TREE_VALUE(hAttrArgs)).to_shwi();
    446                     State.iArgs = TREE_INT_CST(TREE_VALUE(TREE_CHAIN(hAttrArgs))).to_shwi();
    447                     State.hStmt = hStmt;
     513                    State.iFmt    = TREE_INT_CST(TREE_VALUE(hAttrArgs)).to_shwi();
     514                    State.iArgs   = TREE_INT_CST(TREE_VALUE(TREE_CHAIN(hAttrArgs))).to_shwi();
     515                    State.hStmt   = hStmt;
     516                    State.hFmtLoc = gimple_location(hStmt);
    448517                    dprintf("     %s() __iprt_format__(iFmt=%ld, iArgs=%ld)\n",
    449518                            DECL_NAME(hFnDecl) ? IDENTIFIER_POINTER(DECL_NAME(hFnDecl)) : "<unamed>", State.iFmt, State.iArgs);
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette