/******************************************************************************
 *
 * Module Name: aslwalks.c - Miscellaneous analytical parse tree walks
 *
 *****************************************************************************/

/*
 * Copyright (C) 2000 - 2023, Intel Corp.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 */

#include "aslcompiler.h"
#include "aslcompiler.y.h"
#include "acparser.h"
#include "amlcode.h"


#define _COMPONENT          ACPI_COMPILER
        ACPI_MODULE_NAME    ("aslwalks")


/* Local prototypes */

static void
AnAnalyzeStoreOperator (
    ACPI_PARSE_OBJECT       *Op);

static BOOLEAN
AnIsValidBufferConstant (
    ACPI_PARSE_OBJECT       *Op);

static void
AnValidateCreateBufferField (
    ACPI_PARSE_OBJECT       *CreateBufferFieldOp);


/*******************************************************************************
 *
 * FUNCTION:    AnMethodTypingWalkEnd
 *
 * PARAMETERS:  ASL_WALK_CALLBACK
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Ascending callback for typing walk. Complete the method
 *              return analysis. Check methods for:
 *              1) Initialized local variables
 *              2) Valid arguments
 *              3) Return types
 *
 ******************************************************************************/

ACPI_STATUS
AnMethodTypingWalkEnd (
    ACPI_PARSE_OBJECT       *Op,
    UINT32                  Level,
    void                    *Context)
{
    UINT32                  ThisOpBtype;


    switch (Op->Asl.ParseOpcode)
    {
    case PARSEOP_METHOD:

        Op->Asl.CompileFlags |= OP_METHOD_TYPED;
        break;

    case PARSEOP_RETURN:

        if ((Op->Asl.Child) &&
            (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
        {
            ThisOpBtype = AnGetBtype (Op->Asl.Child);

            if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
                (ThisOpBtype == (ACPI_UINT32_MAX -1)))
            {
                /*
                 * The called method is untyped at this time (typically a
                 * forward reference).
                 *
                 * Check for a recursive method call first. Note: the
                 * Child->Node will be null if the method has not been
                 * resolved.
                 */
                if (Op->Asl.Child->Asl.Node &&
                    (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op))
                {
                    /* We must type the method here */

                    TrWalkParseTree (Op->Asl.Child->Asl.Node->Op,
                        ASL_WALK_VISIT_UPWARD, NULL,
                        AnMethodTypingWalkEnd, NULL);

                    ThisOpBtype = AnGetBtype (Op->Asl.Child);
                }
            }

            /* Returns a value, save the value type */

            if (Op->Asl.ParentMethod)
            {
                Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisOpBtype;
            }
        }
        break;

    default:

        break;
    }

    return (AE_OK);
}


/*******************************************************************************
 *
 * FUNCTION:    AnOperandTypecheckWalkEnd
 *
 * PARAMETERS:  ASL_WALK_CALLBACK
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Ascending callback for analysis walk. Complete method
 *              return analysis.
 *
 ******************************************************************************/

ACPI_STATUS
AnOperandTypecheckWalkEnd (
    ACPI_PARSE_OBJECT       *Op,
    UINT32                  Level,
    void                    *Context)
{
    const ACPI_OPCODE_INFO  *OpInfo;
    UINT32                  RuntimeArgTypes;
    UINT32                  RuntimeArgTypes2;
    UINT32                  RequiredBtypes;
    UINT32                  ThisNodeBtype;
    UINT32                  CommonBtypes;
    UINT32                  OpcodeClass;
    ACPI_PARSE_OBJECT       *ArgOp;
    UINT32                  ArgType;


    switch (Op->Asl.AmlOpcode)
    {
    case AML_RAW_DATA_BYTE:
    case AML_RAW_DATA_WORD:
    case AML_RAW_DATA_DWORD:
    case AML_RAW_DATA_QWORD:
    case AML_RAW_DATA_BUFFER:
    case AML_RAW_DATA_CHAIN:
    case AML_PACKAGE_LENGTH:
    case AML_UNASSIGNED_OPCODE:
    case AML_DEFAULT_ARG_OP:

        /* Ignore the internal (compiler-only) AML opcodes */

        return (AE_OK);

    default:

        break;
    }

    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
    if (!OpInfo)
    {
        return (AE_OK);
    }

    ArgOp = Op->Asl.Child;
    OpcodeClass = OpInfo->Class;
    RuntimeArgTypes = OpInfo->RuntimeArgs;

#ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE
    /*
     * Update 11/2008: In practice, we can't perform this check. A simple
     * analysis is not sufficient. Also, it can cause errors when compiling
     * disassembled code because of the way Switch operators are implemented
     * (a While(One) loop with a named temp variable created within.)
     */

    /*
     * If we are creating a named object, check if we are within a while loop
     * by checking if the parent is a WHILE op. This is a simple analysis, but
     * probably sufficient for many cases.
     *
     * Allow Scope(), Buffer(), and Package().
     */
    if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) ||
        ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE)))
    {
        if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP)
        {
            AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL);
        }
    }
#endif

    /*
     * Special case for control opcodes IF/RETURN/WHILE since they
     * have no runtime arg list (at this time)
     */
    switch (Op->Asl.AmlOpcode)
    {
    case AML_IF_OP:
    case AML_WHILE_OP:
    case AML_RETURN_OP:

        if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
        {
            /* Check for an internal method */

            if (AnIsInternalMethod (ArgOp))
            {
                return (AE_OK);
            }

            /* The lone arg is a method call, check it */

            RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
            if (Op->Asl.AmlOpcode == AML_RETURN_OP)
            {
                RequiredBtypes = 0xFFFFFFFF;
            }

            ThisNodeBtype = AnGetBtype (ArgOp);
            if (ThisNodeBtype == ACPI_UINT32_MAX)
            {
                return (AE_OK);
            }

            AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
                RequiredBtypes, ThisNodeBtype);
        }
        return (AE_OK);

    case AML_EXTERNAL_OP:
        /*
         * Not really a "runtime" opcode since it used by disassembler only.
         * The parser will find any issues with the operands.
         */
        return (AE_OK);

    default:

        break;
    }

    /* Ignore the non-executable opcodes */

    if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
    {
        return (AE_OK);
    }

    /*
     * Special handling for certain opcodes.
     */
    switch (Op->Asl.AmlOpcode)
    {
        /* BankField has one TermArg */

    case AML_BANK_FIELD_OP:

        OpcodeClass = AML_CLASS_EXECUTE;
        ArgOp = ArgOp->Asl.Next;
        ArgOp = ArgOp->Asl.Next;
        break;

        /* Operation Region has 2 TermArgs */

    case AML_REGION_OP:

        OpcodeClass = AML_CLASS_EXECUTE;
        ArgOp = ArgOp->Asl.Next;
        ArgOp = ArgOp->Asl.Next;
        break;

        /* DataTableRegion has 3 TermArgs */

    case AML_DATA_REGION_OP:

        OpcodeClass = AML_CLASS_EXECUTE;
        ArgOp = ArgOp->Asl.Next;
        break;

        /* Buffers/Packages have a length that is a TermArg */

    case AML_BUFFER_OP:
    case AML_PACKAGE_OP:
    case AML_VARIABLE_PACKAGE_OP:

            /* If length is a constant, we are done */

        if ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) ||
            (ArgOp->Asl.ParseOpcode == PARSEOP_RAW_DATA))
        {
            return (AE_OK);
        }
        break;

        /* Store can write any object to the Debug object */

    case AML_STORE_OP:
        /*
         * If this is a Store() to the Debug object, we don't need
         * to perform any further validation -- because a Store of
         * any object to Debug is permitted and supported.
         */
        if (ArgOp->Asl.Next->Asl.AmlOpcode == AML_DEBUG_OP)
        {
            return (AE_OK);
        }
        break;

    default:
        break;
    }

    switch (OpcodeClass)
    {
    case AML_CLASS_EXECUTE:
    case AML_CLASS_CREATE:
    case AML_CLASS_CONTROL:
    case AML_CLASS_RETURN_VALUE:

        /* Reverse the runtime argument list */

        RuntimeArgTypes2 = 0;
        while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
        {
            RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
            RuntimeArgTypes2 |= ArgType;
            INCREMENT_ARG_LIST (RuntimeArgTypes);
        }

        /* Typecheck each argument */

        while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
        {
            /* Get the required type(s) for the argument */

            RequiredBtypes = AnMapArgTypeToBtype (ArgType);

            if (!ArgOp)
            {
                AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
                    "Null ArgOp in argument loop");
                AslAbort ();
            }

            /* Get the actual type of the argument */

            ThisNodeBtype = AnGetBtype (ArgOp);
            if (ThisNodeBtype == ACPI_UINT32_MAX)
            {
                goto NextArgument;
            }

            /* Examine the arg based on the required type of the arg */

            switch (ArgType)
            {
            case ARGI_TARGETREF:

                if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
                {
                    /* ZERO is the placeholder for "don't store result" */

                    ThisNodeBtype = RequiredBtypes;
                    break;
                }

                ACPI_FALLTHROUGH;

            case ARGI_STORE_TARGET:

                if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
                {
                    /*
                     * This is the case where an original reference to a resource
                     * descriptor field has been replaced by an (Integer) offset.
                     * These named fields are supported at compile-time only;
                     * the names are not passed to the interpreter (via the AML).
                     */
                    if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
                        (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
                    {
                        AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD,
                            ArgOp, NULL);
                    }
                    else
                    {
                        AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE,
                            ArgOp, NULL);
                    }
                }
                break;


#ifdef __FUTURE_IMPLEMENTATION
/*
 * Possible future typechecking support
 */
            case ARGI_REFERENCE:            /* References */
            case ARGI_INTEGER_REF:
            case ARGI_OBJECT_REF:
            case ARGI_DEVICE_REF:

                switch (ArgOp->Asl.ParseOpcode)
                {
                case PARSEOP_LOCAL0:
                case PARSEOP_LOCAL1:
                case PARSEOP_LOCAL2:
                case PARSEOP_LOCAL3:
                case PARSEOP_LOCAL4:
                case PARSEOP_LOCAL5:
                case PARSEOP_LOCAL6:
                case PARSEOP_LOCAL7:

                    /* TBD: implement analysis of current value (type) of the local */
                    /* For now, just treat any local as a typematch */

                    /*ThisNodeBtype = RequiredBtypes;*/
                    break;

                case PARSEOP_ARG0:
                case PARSEOP_ARG1:
                case PARSEOP_ARG2:
                case PARSEOP_ARG3:
                case PARSEOP_ARG4:
                case PARSEOP_ARG5:
                case PARSEOP_ARG6:

                    /* Hard to analyze argument types, so we won't */
                    /* for now. Just treat any arg as a typematch */

                    /* ThisNodeBtype = RequiredBtypes; */
                    break;

                case PARSEOP_DEBUG:
                case PARSEOP_REFOF:
                case PARSEOP_INDEX:
                default:

                    break;
                }
                break;
#endif
            case ARGI_INTEGER:
            default:

                break;
            }


            /* Check for a type mismatch (required versus actual) */

            CommonBtypes = ThisNodeBtype & RequiredBtypes;

            if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
            {
                if (AnIsInternalMethod (ArgOp))
                {
                    return (AE_OK);
                }

                /* Check a method call for a valid return value */

                AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
                    RequiredBtypes, ThisNodeBtype);
            }

            /*
             * Now check if the actual type(s) match at least one
             * bit to the required type
             */
            else if (!CommonBtypes)
            {
                /* No match -- this is a type mismatch error */

                AnFormatBtype (AslGbl_StringBuffer, ThisNodeBtype);
                AnFormatBtype (AslGbl_StringBuffer2, RequiredBtypes);

                sprintf (AslGbl_MsgBuffer, "[%s] found, %s operator requires [%s]",
                    AslGbl_StringBuffer, OpInfo->Name, AslGbl_StringBuffer2);

                AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE,
                    ArgOp, AslGbl_MsgBuffer);
            }

        NextArgument:
            ArgOp = ArgOp->Asl.Next;
            INCREMENT_ARG_LIST (RuntimeArgTypes2);
        }
        break;

    default:

        break;
    }

    return (AE_OK);
}


/*******************************************************************************
 *
 * FUNCTION:    AnOtherSemanticAnalysisWalkBegin
 *
 * PARAMETERS:  ASL_WALK_CALLBACK
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Descending callback for the analysis walk. Checks for
 *              miscellaneous issues in the code.
 *
 ******************************************************************************/

ACPI_STATUS
AnOtherSemanticAnalysisWalkBegin (
    ACPI_PARSE_OBJECT       *Op,
    UINT32                  Level,
    void                    *Context)
{
    ACPI_PARSE_OBJECT       *ArgOp;
    ACPI_PARSE_OBJECT       *PrevArgOp = NULL;
    const ACPI_OPCODE_INFO  *OpInfo;
    ACPI_NAMESPACE_NODE     *Node;


    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);


    if (OpInfo->Flags & AML_CREATE)
    {
        /* This group contains all of the Create Buffer Field operators */

        AnValidateCreateBufferField (Op);
        return (AE_OK);
    }

    /*
     * Determine if an execution class operator actually does something by
     * checking if it has a target and/or the function return value is used.
     * (Target is optional, so a standalone statement can actually do nothing.)
     */
    if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
        (OpInfo->Flags & AML_HAS_RETVAL) &&
        (!AnIsResultUsed (Op)))
    {
        if (OpInfo->Flags & AML_HAS_TARGET)
        {
            /*
             * Find the target node, it is always the last child. If the target
             * is not specified in the ASL, a default node of type Zero was
             * created by the parser.
             */
            ArgOp = Op->Asl.Child;
            while (ArgOp->Asl.Next)
            {
                PrevArgOp = ArgOp;
                ArgOp = ArgOp->Asl.Next;
            }

            /* Divide() is the only weird case, it has two targets */

            if (Op->Asl.AmlOpcode == AML_DIVIDE_OP)
            {
                if ((ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) &&
                    (PrevArgOp) &&
                    (PrevArgOp->Asl.ParseOpcode == PARSEOP_ZERO))
                {
                    AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
                        Op, Op->Asl.ExternalName);
                }
            }

            else if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
            {
                AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
                    Op, Op->Asl.ExternalName);
            }
        }
        else
        {
            /*
             * Has no target and the result is not used. Only a couple opcodes
             * can have this combination.
             */
            switch (Op->Asl.ParseOpcode)
            {
            case PARSEOP_ACQUIRE:
            case PARSEOP_WAIT:
            case PARSEOP_LOADTABLE:

                break;

            default:

                AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
                    Op, Op->Asl.ExternalName);
                break;
            }
        }
    }

    /*
     * Semantic checks for individual ASL operators
     */

    switch (Op->Asl.ParseOpcode)
    {
    case PARSEOP_STORE:

        if (AslGbl_DoTypechecking)
        {
            AnAnalyzeStoreOperator (Op);
        }
        break;


    case PARSEOP_ACQUIRE:
    case PARSEOP_WAIT:
        /*
         * Emit a warning if the timeout parameter for these operators is not
         * ACPI_WAIT_FOREVER, and the result value from the operator is not
         * checked, meaning that a timeout could happen, but the code
         * would not know about it.
         */

        /* First child is the namepath, 2nd child is timeout */

        ArgOp = Op->Asl.Child;
        ArgOp = ArgOp->Asl.Next;

        /*
         * Check for the WAIT_FOREVER case - defined by the ACPI spec to be
         * 0xFFFF or greater
         */
        if (((ArgOp->Asl.ParseOpcode == PARSEOP_WORDCONST) ||
             (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER))  &&
             (ArgOp->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER))
        {
            break;
        }

        /*
         * The operation could timeout. If the return value is not used
         * (indicates timeout occurred), issue a warning
         */
        if (!AnIsResultUsed (Op))
        {
            AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgOp,
                Op->Asl.ExternalName);
        }
        break;

    case PARSEOP_CONNECTION:
        /*
         * Ensure that the referenced operation region has the correct SPACE_ID.
         * From the grammar/parser, we know the parent is a FIELD definition.
         */
        ArgOp = Op->Asl.Parent;     /* Field definition */
        ArgOp = ArgOp->Asl.Child;   /* First child is the OpRegion Name */
        Node = ArgOp->Asl.Node;     /* OpRegion namespace node */
        if (!Node)
        {
            break;
        }

        ArgOp = Node->Op;           /* OpRegion definition */
        ArgOp = ArgOp->Asl.Child;   /* First child is the OpRegion Name */
        ArgOp = ArgOp->Asl.Next;    /* Next peer is the SPACE_ID (what we want) */

        /*
         * The Connection() operator is only valid for the following operation
         * region SpaceIds: GeneralPurposeIo and GenericSerialBus.
         */
        if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) &&
            (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS))
        {
            AslError (ASL_ERROR, ASL_MSG_CONNECTION_INVALID, Op, NULL);
        }
        break;

    case PARSEOP_FIELD:
        /*
         * Ensure that fields for GeneralPurposeIo and GenericSerialBus
         * contain at least one Connection() operator
         */
        ArgOp = Op->Asl.Child;      /* 1st child is the OpRegion Name */
        Node = ArgOp->Asl.Node;     /* OpRegion namespace node */
        if (!Node)
        {
            break;
        }

        ArgOp = Node->Op;           /* OpRegion definition */
        ArgOp = ArgOp->Asl.Child;   /* First child is the OpRegion Name */
        ArgOp = ArgOp->Asl.Next;    /* Next peer is the SPACE_ID (what we want) */

        /* We are only interested in GeneralPurposeIo and GenericSerialBus */

        if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) &&
            (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS))
        {
            break;
        }

        ArgOp = Op->Asl.Child;      /* 1st child is the OpRegion Name */
        ArgOp = ArgOp->Asl.Next;    /* AccessType */
        ArgOp = ArgOp->Asl.Next;    /* LockRule */
        ArgOp = ArgOp->Asl.Next;    /* UpdateRule */
        ArgOp = ArgOp->Asl.Next;    /* Start of FieldUnitList */

        /* Walk the FieldUnitList */

        while (ArgOp)
        {
            if (ArgOp->Asl.ParseOpcode == PARSEOP_CONNECTION)
            {
                break;
            }
            else if (ArgOp->Asl.ParseOpcode == PARSEOP_NAMESEG)
            {
                AslError (ASL_ERROR, ASL_MSG_CONNECTION_MISSING, ArgOp, NULL);
                break;
            }

            ArgOp = ArgOp->Asl.Next;
        }
        break;

    default:

        break;
    }

    return (AE_OK);
}


/*******************************************************************************
 *
 * FUNCTION:    AnValidateCreateBufferField
 *
 * PARAMETERS:  Op                  - A create buffer field operator
 *
 * RETURN:      None
 *
 * DESCRIPTION: Check if a buffer index argument to a create buffer field
 *              operation is beyond the end of the target buffer.
 *
 *  Validates these AML operators:
 *
 *  AML_CREATE_FIELD_OP
 *  AML_CREATE_BIT_FIELD_OP
 *  AML_CREATE_BYTE_FIELD_OP
 *  AML_CREATE_WORD_FIELD_OP
 *  AML_CREATE_DWORD_FIELD_OP
 *  AML_CREATE_QWORD_FIELD_OP
 *
 *  There are two conditions that must be satisfied in order to enable
 *  validation at compile time:
 *
 *  1) The length of the target buffer must be an integer constant
 *  2) The index specified in the create* must be an integer constant
 *  3) For CreateField, the bit length argument must be non-zero.
 *
 ******************************************************************************/

static void
AnValidateCreateBufferField (
    ACPI_PARSE_OBJECT       *CreateBufferFieldOp)
{
    ACPI_PARSE_OBJECT       *TargetBufferOp;
    ACPI_PARSE_OBJECT       *ArgOp;
    UINT32                  TargetBufferLength;
    UINT32                  LastFieldByteIndex;


    /*
     * 1) Get the length of the target buffer
     */
    ArgOp = CreateBufferFieldOp->Asl.Child;     /* Reference to target buffer */

    /*
     * If no attached Node, the target buffer may be something like an
     * ArgX or LocalX and cannot be evaluated at compile time.
     */
    if (!ArgOp->Asl.Node)
    {
        return;
    }

    TargetBufferOp = ArgOp->Asl.Node->Op;
    TargetBufferOp = TargetBufferOp->Asl.Child; /* Target buffer */
    TargetBufferOp = TargetBufferOp->Asl.Next;  /* "Buffer" keyword */
    if (!TargetBufferOp)
    {
        /* Not a statement of the form NAME(XXXX, Buffer.... */

        return;
    }

    /* Get the buffer length argument. It must be an integer constant */

    ArgOp = TargetBufferOp->Asl.Child;
    if (!AnIsValidBufferConstant (ArgOp))
    {
        return;
    }

    TargetBufferLength = (UINT32) ArgOp->Asl.Value.Integer;

    /*
     * 2) Get the value of the buffer index argument. It must be
     * an integer constant.
     */
    ArgOp = CreateBufferFieldOp->Asl.Child;     /* Reference to target buffer */
    ArgOp = ArgOp->Asl.Next;                    /* Buffer Index argument*/
    if (!AnIsValidBufferConstant (ArgOp))
    {
        return;
    }

    LastFieldByteIndex =
        (UINT32) ArgOp->Asl.Value.Integer;      /* Index can be in either bytes or bits */

    /*
     * 3) Get the length of the new buffer field, in bytes. Also,
     * create the final target buffer index for the last byte of the field
     */
    switch (CreateBufferFieldOp->Asl.ParseOpcode)
    {
    case PARSEOP_CREATEBITFIELD:                /* A one bit field */

        LastFieldByteIndex = ACPI_ROUND_BITS_DOWN_TO_BYTES (LastFieldByteIndex);
        break;

    case PARSEOP_CREATEBYTEFIELD:
        break;

    case PARSEOP_CREATEWORDFIELD:

        LastFieldByteIndex += (sizeof (UINT16) - 1);
        break;

    case PARSEOP_CREATEDWORDFIELD:

        LastFieldByteIndex += (sizeof (UINT32) - 1);
        break;

    case PARSEOP_CREATEQWORDFIELD:

        LastFieldByteIndex += (sizeof (UINT64) - 1);
        break;

    case PARSEOP_CREATEFIELD:                   /* Multi-bit field */

        ArgOp = ArgOp->Asl.Next;                /* Length argument, in bits */
        if (!AnIsValidBufferConstant (ArgOp))
        {
            return;
        }

        /* The buffer field length is not allowed to be zero */

        if (ArgOp->Asl.Value.Integer == 0)
        {
            AslError (ASL_WARNING,  ASL_MSG_BUFFER_FIELD_LENGTH, ArgOp, NULL);
            return;
        }

        LastFieldByteIndex +=
            ((UINT32) ArgOp->Asl.Value.Integer - 1);    /* Create final bit index */

        /* Convert bit index to a byte index */

        LastFieldByteIndex = ACPI_ROUND_BITS_DOWN_TO_BYTES (LastFieldByteIndex);
        break;

    default:
        return;
    }

    /*
     * 4) Check for an access (index) beyond the end of the target buffer,
     * or a zero length target buffer.
     */
    if (!TargetBufferLength || (LastFieldByteIndex >= TargetBufferLength))
    {
        AslError (ASL_WARNING, ASL_MSG_BUFFER_FIELD_OVERFLOW, ArgOp, NULL);
    }
}


/*******************************************************************************
 *
 * FUNCTION:    AnIsValidBufferConstant
 *
 * PARAMETERS:  Op                  - A buffer-related operand
 *
 * RETURN:      TRUE if operand is valid constant, FALSE otherwise
 *
 * DESCRIPTION: Check if the input Op is valid constant that can be used
 *              in compile-time analysis.
 *
 ******************************************************************************/

static BOOLEAN
AnIsValidBufferConstant (
    ACPI_PARSE_OBJECT       *Op)
{
    if (!Op)
    {
        return (FALSE);
    }

    if ((Op->Asl.ParseOpcode == PARSEOP_INTEGER) ||
        (Op->Asl.ParseOpcode == PARSEOP_ZERO)    ||
        (Op->Asl.ParseOpcode == PARSEOP_ONE))
    {
        return (TRUE);
    }

    return (FALSE);
}


/*******************************************************************************
 *
 * FUNCTION:    AnAnalyzeStoreOperator
 *
 * PARAMETERS:  Op                  - Store() operator
 *
 * RETURN:      None
 *
 * DESCRIPTION: Analyze a store operator. Mostly for stores to/from package
 *              objects where there are more restrictions than other data
 *              types.
 *
 ******************************************************************************/

static void
AnAnalyzeStoreOperator (
    ACPI_PARSE_OBJECT       *Op)
{
    ACPI_NAMESPACE_NODE     *SourceNode;
    ACPI_NAMESPACE_NODE     *TargetNode;
    ACPI_PARSE_OBJECT       *SourceOperandOp;
    ACPI_PARSE_OBJECT       *TargetOperandOp;
    UINT32                  SourceOperandBtype;
    UINT32                  TargetOperandBtype;


    /* Extract the two operands for STORE */

    SourceOperandOp = Op->Asl.Child;
    TargetOperandOp = SourceOperandOp->Asl.Next;

    /*
     * Ignore these Source operand opcodes, they cannot be typechecked,
     * the actual result is unknown here.
     */
    switch (SourceOperandOp->Asl.ParseOpcode)
    {
    /* For these, type of the returned value is unknown at compile time */

    case PARSEOP_DEREFOF:
    case PARSEOP_METHODCALL:
    case PARSEOP_STORE:
    case PARSEOP_COPYOBJECT:

        return;

    case PARSEOP_INDEX:
    case PARSEOP_REFOF:

        if (!AslGbl_EnableReferenceTypechecking)
        {
            return;
        }

        /*
         * These opcodes always return an object reference, and thus
         * the result can only be stored to a Local, Arg, or Debug.
         */
        if (TargetOperandOp->Asl.AmlOpcode == AML_DEBUG_OP)
        {
            return;
        }

        if ((TargetOperandOp->Asl.AmlOpcode < AML_LOCAL0) ||
            (TargetOperandOp->Asl.AmlOpcode > AML_ARG6))
        {
            AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp,
                "Source [Reference], Target must be [Local/Arg/Debug]");
        }
        return;

    default:
        break;
    }

    /*
     * Ignore these Target operand opcodes, they cannot be typechecked
     */
    switch (TargetOperandOp->Asl.ParseOpcode)
    {
    case PARSEOP_DEBUG:
    case PARSEOP_DEREFOF:
    case PARSEOP_REFOF:
    case PARSEOP_INDEX:
    case PARSEOP_STORE:

        return;

    default:
        break;
    }

    /*
     * Ignore typecheck for External() operands of type "UnknownObj",
     * we don't know the actual type (source or target).
     */
    SourceNode = SourceOperandOp->Asl.Node;
    if (SourceNode &&
        (SourceNode->Flags & ANOBJ_IS_EXTERNAL) &&
        (SourceNode->Type == ACPI_TYPE_ANY))
    {
        return;
    }

    TargetNode = TargetOperandOp->Asl.Node;
    if (TargetNode &&
        (TargetNode->Flags & ANOBJ_IS_EXTERNAL) &&
        (TargetNode->Type == ACPI_TYPE_ANY))
    {
        return;
    }

    /*
     * A NULL node with a namepath AML opcode indicates non-existent
     * name. Just return, the error message is generated elsewhere.
     */
    if ((!SourceNode && (SourceOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)) ||
        (!TargetNode && (TargetOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)))
    {
        return;
    }

    /*
     * Simple check for source same as target via NS node.
     * -- Could be expanded to locals and args.
     */
    if (SourceNode && TargetNode)
    {
        if (SourceNode == TargetNode)
        {
            AslError (ASL_WARNING, ASL_MSG_DUPLICATE_ITEM,
                TargetOperandOp, "Source is the same as Target");
            return;
        }
    }

    /* Ignore typecheck if either source or target is a local or arg */

    if ((SourceOperandOp->Asl.AmlOpcode >= AML_LOCAL0) &&
        (SourceOperandOp->Asl.AmlOpcode <= AML_ARG6))
    {
        return; /* Cannot type a local/arg at compile time */
    }

    if ((TargetOperandOp->Asl.AmlOpcode >= AML_LOCAL0) &&
        (TargetOperandOp->Asl.AmlOpcode <= AML_ARG6))
    {
        return; /* Cannot type a local/arg at compile time */
    }

    /*
     * Package objects are a special case because they cannot by implicitly
     * converted to/from anything. Check for these two illegal cases:
     *
     *      Store (non-package, package)
     *      Store (package, non-package)
     */
    SourceOperandBtype = AnGetBtype (SourceOperandOp);
    TargetOperandBtype = AnGetBtype (TargetOperandOp);

    /* Check source first for (package, non-package) case */

    if (SourceOperandBtype & ACPI_BTYPE_PACKAGE)
    {
        /* If Source is PACKAGE-->Target must be PACKAGE */

        if (!(TargetOperandBtype & ACPI_BTYPE_PACKAGE))
        {
            AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp,
                "Source is [Package], Target must be a package also");
        }
    }

    /* Else check target for (non-package, package) case */

    else if (TargetOperandBtype & ACPI_BTYPE_PACKAGE)
    {
        /* If Target is PACKAGE, Source must be PACKAGE */

        if (!(SourceOperandBtype & ACPI_BTYPE_PACKAGE))
        {
            AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, SourceOperandOp,
                "Target is [Package], Source must be a package also");
        }
    }
}
