Example #1
0
        protected void FindUnhandledExceptions()
        {
            Hashtable methodExMarks = this.GetExceptionMarks();
            bool      hasHandlers   = true;

            if (methodExMarks.Count > 0)
            {
                //  This method can throw exceptions.
                ArrayList exHandlers = this.mTargetMethod.RetrieveEHClauses();

                if (exHandlers != null && exHandlers.Count > 0)
                {
                    //  Remove the unneeded handlers.
                    for (int i = exHandlers.Count - 1; i >= 0; i--)
                    {
                        EHClause cTest = (EHClause)exHandlers[i];

                        if (cTest.Type != EHClauseTypes.EHNone)
                        {
                            exHandlers.Remove(cTest);
                        }
                    }

                    if (exHandlers.Count > 0)
                    {
                        foreach (object key in methodExMarks.Keys)
                        {
                            uint      keyValue        = (uint)((int)key);
                            ArrayList foundExceptions = (ArrayList)methodExMarks[key];
                            foreach (Type foundExType in foundExceptions)
                            {
                                bool areAllTryBlocksProcessed = false;
                                bool isHandled   = false;
                                int  maxDistance = this.mCIL.Length;
                                int  minDistance = -1;

                                do
                                {
                                    bool foundOneHandler = false;

                                    foreach (EHClause clause in exHandlers)
                                    {
                                        uint tryEnd = clause.TryOffset + clause.TryLength;
                                        if (keyValue >= clause.TryOffset &&
                                            keyValue <= tryEnd)
                                        {
                                            int distance = Math.Abs((int)clause.TryOffset - (int)keyValue) +
                                                           Math.Abs((int)tryEnd - (int)keyValue);
                                            if (distance <= maxDistance && distance > minDistance)
                                            {
                                                foundOneHandler = true;
                                                maxDistance     = distance;
                                                Type handlerEx = Type.GetType(
                                                    ILServices.GetNameForToken(this.mTargetMethod.ModuleName,
                                                                               clause.ClassTokenOrFilterOffset));

                                                if (foundExType == handlerEx ||
                                                    foundExType.IsSubclassOf(handlerEx))
                                                {
                                                    isHandled = true;
                                                    areAllTryBlocksProcessed = true;
                                                    break;
                                                }
                                            }
                                        }
                                    }

                                    if (foundOneHandler == true)
                                    {
                                        minDistance = maxDistance;
                                    }
                                    else
                                    {
                                        areAllTryBlocksProcessed = true;
                                    }
                                } while(areAllTryBlocksProcessed == false);

                                if (isHandled == false)
                                {
                                    this.CheckExceptionTypeInThrowsAttribute(foundExType);
                                }
                            }
                        }
                    }
                    else
                    {
                        hasHandlers = false;
                    }
                }
                else
                {
                    hasHandlers = false;
                }

                if (hasHandlers == false)
                {
                    //  ALL of the found exceptions from GetExceptionMarks()
                    //  must be marked by this method, or it's a compilation error
                    foreach (object key in methodExMarks.Keys)
                    {
                        uint      keyValue        = (uint)(int)key;
                        ArrayList foundExceptions = (ArrayList)methodExMarks[key];
                        foreach (Type foundEx in foundExceptions)
                        {
                            this.CheckExceptionTypeInThrowsAttribute(foundEx);
                        }
                    }
                }
            }
        }
Example #2
0
        private static void FindNextBlockStart(EHClausesArray clauses, out BlockType blockType, ref int blockStart, ref int blockEnd, out Type catchBlockType, out int index)
        {
            //given a block [blockStart,blockEnd) we search for the block [newBlockStart,newBlockEnd) such that:
            //1) IsBlockLater([blockStart,blockEnd) , [newBlockStart,newBlockEnd))
            //2) if   IsBlockLater([blockStart,blockEnd) , [newBlockStart',newBlockEnd'))
            //   then IsBlockLater([newBlockStart,newBlockEnd) , [newBlockStart',newBlockEnd'))
            int newBlockStart = 1 << 30;
            int newBlockEnd   = 1 << 30;

            blockType      = BlockType.None;
            catchBlockType = null;
            index          = -1;
            for (int i = 0; i < clauses.Count; i++)
            {
                EHClause c = clauses[i];
                if (IsBlockLater(blockStart, blockEnd, c.TryStart, c.TryEnd) &&
                    IsBlockLater(c.TryStart, c.TryEnd, newBlockStart, newBlockEnd))
                {
                    blockType     = BlockType.Try;
                    newBlockStart = c.TryStart;
                    newBlockEnd   = c.TryEnd;
                    index         = i;
                }
                if (IsBlockLater(blockStart, blockEnd, c.HandlerStart, c.HandlerEnd) &&
                    IsBlockLater(c.HandlerStart, c.HandlerEnd, newBlockStart, newBlockEnd))
                {                 //Andrew: mb treat filters another way...
                    newBlockStart = c.HandlerStart;
                    newBlockEnd   = c.HandlerEnd;
                    index         = i;
                    switch (c.Kind)
                    {
                    case EHClauseKind.FinallyHandler:
                        blockType = BlockType.Finally;
                        break;

                    case EHClauseKind.TypeFilteredHandler:
                        blockType      = BlockType.Catch;
                        catchBlockType = c.ClassObject;
                        break;

                    case EHClauseKind.FaultHandler:
                        blockType = BlockType.Catch;
                        break;

                    case EHClauseKind.UserFilteredHandler:
                        blockType = BlockType.FilteredCatch;
                        break;
                    }
                }
                if (c.Kind == EHClauseKind.UserFilteredHandler)
                {
                    if (IsBlockLater(blockStart, blockEnd, c.FilterStart, c.FilterEnd) &&
                        IsBlockLater(c.FilterStart, c.FilterEnd, newBlockStart, newBlockEnd))
                    {
                        newBlockStart = c.FilterStart;
                        newBlockEnd   = c.FilterEnd;
                        blockType     = BlockType.Filter;
                        index         = i;
                    }
                }
            }
            blockStart = newBlockStart;
            blockEnd   = newBlockEnd;
        }