1efcc2a30SJung-uk Kim /****************************************************************************** 2efcc2a30SJung-uk Kim * 3efcc2a30SJung-uk Kim * Module Name: aslmethod.c - Control method analysis walk 4efcc2a30SJung-uk Kim * 5efcc2a30SJung-uk Kim *****************************************************************************/ 6efcc2a30SJung-uk Kim 7efcc2a30SJung-uk Kim /* 8f8146b88SJung-uk Kim * Copyright (C) 2000 - 2016, Intel Corp. 9efcc2a30SJung-uk Kim * All rights reserved. 10efcc2a30SJung-uk Kim * 11efcc2a30SJung-uk Kim * Redistribution and use in source and binary forms, with or without 12efcc2a30SJung-uk Kim * modification, are permitted provided that the following conditions 13efcc2a30SJung-uk Kim * are met: 14efcc2a30SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 15efcc2a30SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 16efcc2a30SJung-uk Kim * without modification. 17efcc2a30SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18efcc2a30SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 19efcc2a30SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 20efcc2a30SJung-uk Kim * including a substantially similar Disclaimer requirement for further 21efcc2a30SJung-uk Kim * binary redistribution. 22efcc2a30SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 23efcc2a30SJung-uk Kim * of any contributors may be used to endorse or promote products derived 24efcc2a30SJung-uk Kim * from this software without specific prior written permission. 25efcc2a30SJung-uk Kim * 26efcc2a30SJung-uk Kim * Alternatively, this software may be distributed under the terms of the 27efcc2a30SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 28efcc2a30SJung-uk Kim * Software Foundation. 29efcc2a30SJung-uk Kim * 30efcc2a30SJung-uk Kim * NO WARRANTY 31efcc2a30SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32efcc2a30SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33efcc2a30SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34efcc2a30SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35efcc2a30SJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36efcc2a30SJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37efcc2a30SJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38efcc2a30SJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39efcc2a30SJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40efcc2a30SJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41efcc2a30SJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 42efcc2a30SJung-uk Kim */ 43efcc2a30SJung-uk Kim 44efcc2a30SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h> 45efcc2a30SJung-uk Kim #include "aslcompiler.y.h" 46a9d8d09cSJung-uk Kim #include <contrib/dev/acpica/include/acparser.h> 47a9d8d09cSJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h> 48efcc2a30SJung-uk Kim 49efcc2a30SJung-uk Kim 50efcc2a30SJung-uk Kim #define _COMPONENT ACPI_COMPILER 51efcc2a30SJung-uk Kim ACPI_MODULE_NAME ("aslmethod") 52efcc2a30SJung-uk Kim 53efcc2a30SJung-uk Kim 54a9d8d09cSJung-uk Kim /* Local prototypes */ 55a9d8d09cSJung-uk Kim 56f8146b88SJung-uk Kim static void 57a9d8d09cSJung-uk Kim MtCheckNamedObjectInMethod ( 58a9d8d09cSJung-uk Kim ACPI_PARSE_OBJECT *Op, 59a9d8d09cSJung-uk Kim ASL_METHOD_INFO *MethodInfo); 60a9d8d09cSJung-uk Kim 61a9d8d09cSJung-uk Kim 62efcc2a30SJung-uk Kim /******************************************************************************* 63efcc2a30SJung-uk Kim * 64efcc2a30SJung-uk Kim * FUNCTION: MtMethodAnalysisWalkBegin 65efcc2a30SJung-uk Kim * 66efcc2a30SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 67efcc2a30SJung-uk Kim * 68efcc2a30SJung-uk Kim * RETURN: Status 69efcc2a30SJung-uk Kim * 70efcc2a30SJung-uk Kim * DESCRIPTION: Descending callback for the analysis walk. Check methods for: 71efcc2a30SJung-uk Kim * 1) Initialized local variables 72efcc2a30SJung-uk Kim * 2) Valid arguments 73efcc2a30SJung-uk Kim * 3) Return types 74efcc2a30SJung-uk Kim * 75efcc2a30SJung-uk Kim ******************************************************************************/ 76efcc2a30SJung-uk Kim 77efcc2a30SJung-uk Kim ACPI_STATUS 78efcc2a30SJung-uk Kim MtMethodAnalysisWalkBegin ( 79efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *Op, 80efcc2a30SJung-uk Kim UINT32 Level, 81efcc2a30SJung-uk Kim void *Context) 82efcc2a30SJung-uk Kim { 83efcc2a30SJung-uk Kim ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context; 84efcc2a30SJung-uk Kim ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack; 85efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *Next; 86efcc2a30SJung-uk Kim UINT32 RegisterNumber; 87efcc2a30SJung-uk Kim UINT32 i; 88efcc2a30SJung-uk Kim char LocalName[] = "Local0"; 89efcc2a30SJung-uk Kim char ArgName[] = "Arg0"; 90efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *ArgNode; 91efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *NextType; 92efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *NextParamType; 93efcc2a30SJung-uk Kim UINT8 ActualArgs = 0; 94efcc2a30SJung-uk Kim 95efcc2a30SJung-uk Kim 96f8146b88SJung-uk Kim /* Build cross-reference output file if requested */ 97f8146b88SJung-uk Kim 98f8146b88SJung-uk Kim if (Gbl_CrossReferenceOutput) 99f8146b88SJung-uk Kim { 100f8146b88SJung-uk Kim OtXrefWalkPart1 (Op, Level, MethodInfo); 101f8146b88SJung-uk Kim } 102f8146b88SJung-uk Kim 103efcc2a30SJung-uk Kim switch (Op->Asl.ParseOpcode) 104efcc2a30SJung-uk Kim { 105efcc2a30SJung-uk Kim case PARSEOP_METHOD: 106efcc2a30SJung-uk Kim 107efcc2a30SJung-uk Kim TotalMethods++; 108efcc2a30SJung-uk Kim 109efcc2a30SJung-uk Kim /* Create and init method info */ 110efcc2a30SJung-uk Kim 111efcc2a30SJung-uk Kim MethodInfo = UtLocalCalloc (sizeof (ASL_METHOD_INFO)); 112efcc2a30SJung-uk Kim MethodInfo->Next = WalkInfo->MethodStack; 113efcc2a30SJung-uk Kim MethodInfo->Op = Op; 114efcc2a30SJung-uk Kim 115efcc2a30SJung-uk Kim WalkInfo->MethodStack = MethodInfo; 116efcc2a30SJung-uk Kim 117313a0c13SJung-uk Kim /* 118313a0c13SJung-uk Kim * Special handling for _PSx methods. Dependency rules (same scope): 119313a0c13SJung-uk Kim * 120313a0c13SJung-uk Kim * 1) _PS0 - One of these must exist: _PS1, _PS2, _PS3 121313a0c13SJung-uk Kim * 2) _PS1/_PS2/_PS3: A _PS0 must exist 122313a0c13SJung-uk Kim */ 123313a0c13SJung-uk Kim if (ACPI_COMPARE_NAME (METHOD_NAME__PS0, Op->Asl.NameSeg)) 124313a0c13SJung-uk Kim { 125313a0c13SJung-uk Kim /* For _PS0, one of _PS1/_PS2/_PS3 must exist */ 126313a0c13SJung-uk Kim 127313a0c13SJung-uk Kim if ((!ApFindNameInScope (METHOD_NAME__PS1, Op)) && 128313a0c13SJung-uk Kim (!ApFindNameInScope (METHOD_NAME__PS2, Op)) && 129313a0c13SJung-uk Kim (!ApFindNameInScope (METHOD_NAME__PS3, Op))) 130313a0c13SJung-uk Kim { 131313a0c13SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op, 132313a0c13SJung-uk Kim "_PS0 requires one of _PS1/_PS2/_PS3 in same scope"); 133313a0c13SJung-uk Kim } 134313a0c13SJung-uk Kim } 135313a0c13SJung-uk Kim else if ( 136313a0c13SJung-uk Kim ACPI_COMPARE_NAME (METHOD_NAME__PS1, Op->Asl.NameSeg) || 137313a0c13SJung-uk Kim ACPI_COMPARE_NAME (METHOD_NAME__PS2, Op->Asl.NameSeg) || 138313a0c13SJung-uk Kim ACPI_COMPARE_NAME (METHOD_NAME__PS3, Op->Asl.NameSeg)) 139313a0c13SJung-uk Kim { 140313a0c13SJung-uk Kim /* For _PS1/_PS2/_PS3, a _PS0 must exist */ 141313a0c13SJung-uk Kim 142313a0c13SJung-uk Kim if (!ApFindNameInScope (METHOD_NAME__PS0, Op)) 143313a0c13SJung-uk Kim { 144313a0c13SJung-uk Kim sprintf (MsgBuffer, 145313a0c13SJung-uk Kim "%4.4s requires _PS0 in same scope", Op->Asl.NameSeg); 146313a0c13SJung-uk Kim 147313a0c13SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op, 148313a0c13SJung-uk Kim MsgBuffer); 149313a0c13SJung-uk Kim } 150313a0c13SJung-uk Kim } 151313a0c13SJung-uk Kim 152313a0c13SJung-uk Kim /* Get the name node */ 153efcc2a30SJung-uk Kim 154efcc2a30SJung-uk Kim Next = Op->Asl.Child; 155efcc2a30SJung-uk Kim 156efcc2a30SJung-uk Kim /* Get the NumArguments node */ 157efcc2a30SJung-uk Kim 158efcc2a30SJung-uk Kim Next = Next->Asl.Next; 159efcc2a30SJung-uk Kim MethodInfo->NumArguments = (UINT8) 160efcc2a30SJung-uk Kim (((UINT8) Next->Asl.Value.Integer) & 0x07); 161efcc2a30SJung-uk Kim 162efcc2a30SJung-uk Kim /* Get the SerializeRule and SyncLevel nodes, ignored here */ 163efcc2a30SJung-uk Kim 164efcc2a30SJung-uk Kim Next = Next->Asl.Next; 165a9d8d09cSJung-uk Kim MethodInfo->ShouldBeSerialized = (UINT8) Next->Asl.Value.Integer; 166a9d8d09cSJung-uk Kim 167efcc2a30SJung-uk Kim Next = Next->Asl.Next; 168efcc2a30SJung-uk Kim ArgNode = Next; 169efcc2a30SJung-uk Kim 170efcc2a30SJung-uk Kim /* Get the ReturnType node */ 171efcc2a30SJung-uk Kim 172efcc2a30SJung-uk Kim Next = Next->Asl.Next; 173efcc2a30SJung-uk Kim 174efcc2a30SJung-uk Kim NextType = Next->Asl.Child; 175efcc2a30SJung-uk Kim while (NextType) 176efcc2a30SJung-uk Kim { 177efcc2a30SJung-uk Kim /* Get and map each of the ReturnTypes */ 178efcc2a30SJung-uk Kim 179efcc2a30SJung-uk Kim MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType); 180efcc2a30SJung-uk Kim NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 181efcc2a30SJung-uk Kim NextType = NextType->Asl.Next; 182efcc2a30SJung-uk Kim } 183efcc2a30SJung-uk Kim 184efcc2a30SJung-uk Kim /* Get the ParameterType node */ 185efcc2a30SJung-uk Kim 186efcc2a30SJung-uk Kim Next = Next->Asl.Next; 187efcc2a30SJung-uk Kim 188efcc2a30SJung-uk Kim NextType = Next->Asl.Child; 189efcc2a30SJung-uk Kim while (NextType) 190efcc2a30SJung-uk Kim { 191efcc2a30SJung-uk Kim if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 192efcc2a30SJung-uk Kim { 193efcc2a30SJung-uk Kim NextParamType = NextType->Asl.Child; 194efcc2a30SJung-uk Kim while (NextParamType) 195efcc2a30SJung-uk Kim { 196f8146b88SJung-uk Kim MethodInfo->ValidArgTypes[ActualArgs] |= 197f8146b88SJung-uk Kim AnMapObjTypeToBtype (NextParamType); 198f8146b88SJung-uk Kim 199efcc2a30SJung-uk Kim NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 200efcc2a30SJung-uk Kim NextParamType = NextParamType->Asl.Next; 201efcc2a30SJung-uk Kim } 202efcc2a30SJung-uk Kim } 203efcc2a30SJung-uk Kim else 204efcc2a30SJung-uk Kim { 205efcc2a30SJung-uk Kim MethodInfo->ValidArgTypes[ActualArgs] = 206efcc2a30SJung-uk Kim AnMapObjTypeToBtype (NextType); 207f8146b88SJung-uk Kim 208efcc2a30SJung-uk Kim NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 209efcc2a30SJung-uk Kim ActualArgs++; 210efcc2a30SJung-uk Kim } 211efcc2a30SJung-uk Kim 212efcc2a30SJung-uk Kim NextType = NextType->Asl.Next; 213efcc2a30SJung-uk Kim } 214efcc2a30SJung-uk Kim 215efcc2a30SJung-uk Kim if ((MethodInfo->NumArguments) && 216efcc2a30SJung-uk Kim (MethodInfo->NumArguments != ActualArgs)) 217efcc2a30SJung-uk Kim { 218efcc2a30SJung-uk Kim /* error: Param list did not match number of args */ 219efcc2a30SJung-uk Kim } 220efcc2a30SJung-uk Kim 221efcc2a30SJung-uk Kim /* Allow numarguments == 0 for Function() */ 222efcc2a30SJung-uk Kim 223efcc2a30SJung-uk Kim if ((!MethodInfo->NumArguments) && (ActualArgs)) 224efcc2a30SJung-uk Kim { 225efcc2a30SJung-uk Kim MethodInfo->NumArguments = ActualArgs; 226efcc2a30SJung-uk Kim ArgNode->Asl.Value.Integer |= ActualArgs; 227efcc2a30SJung-uk Kim } 228efcc2a30SJung-uk Kim 229efcc2a30SJung-uk Kim /* 230efcc2a30SJung-uk Kim * Actual arguments are initialized at method entry. 231efcc2a30SJung-uk Kim * All other ArgX "registers" can be used as locals, so we 232efcc2a30SJung-uk Kim * track their initialization. 233efcc2a30SJung-uk Kim */ 234efcc2a30SJung-uk Kim for (i = 0; i < MethodInfo->NumArguments; i++) 235efcc2a30SJung-uk Kim { 236efcc2a30SJung-uk Kim MethodInfo->ArgInitialized[i] = TRUE; 237efcc2a30SJung-uk Kim } 238efcc2a30SJung-uk Kim break; 239efcc2a30SJung-uk Kim 240efcc2a30SJung-uk Kim case PARSEOP_METHODCALL: 241efcc2a30SJung-uk Kim 242efcc2a30SJung-uk Kim if (MethodInfo && 243efcc2a30SJung-uk Kim (Op->Asl.Node == MethodInfo->Op->Asl.Node)) 244efcc2a30SJung-uk Kim { 245efcc2a30SJung-uk Kim AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName); 246efcc2a30SJung-uk Kim } 247efcc2a30SJung-uk Kim break; 248efcc2a30SJung-uk Kim 249efcc2a30SJung-uk Kim case PARSEOP_LOCAL0: 250efcc2a30SJung-uk Kim case PARSEOP_LOCAL1: 251efcc2a30SJung-uk Kim case PARSEOP_LOCAL2: 252efcc2a30SJung-uk Kim case PARSEOP_LOCAL3: 253efcc2a30SJung-uk Kim case PARSEOP_LOCAL4: 254efcc2a30SJung-uk Kim case PARSEOP_LOCAL5: 255efcc2a30SJung-uk Kim case PARSEOP_LOCAL6: 256efcc2a30SJung-uk Kim case PARSEOP_LOCAL7: 257efcc2a30SJung-uk Kim 258efcc2a30SJung-uk Kim if (!MethodInfo) 259efcc2a30SJung-uk Kim { 260efcc2a30SJung-uk Kim /* 261efcc2a30SJung-uk Kim * Local was used outside a control method, or there was an error 262efcc2a30SJung-uk Kim * in the method declaration. 263efcc2a30SJung-uk Kim */ 264f8146b88SJung-uk Kim AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, 265f8146b88SJung-uk Kim Op, Op->Asl.ExternalName); 266efcc2a30SJung-uk Kim return (AE_ERROR); 267efcc2a30SJung-uk Kim } 268efcc2a30SJung-uk Kim 269fe0f0bbbSJung-uk Kim RegisterNumber = (Op->Asl.AmlOpcode & 0x0007); 270efcc2a30SJung-uk Kim 271efcc2a30SJung-uk Kim /* 272efcc2a30SJung-uk Kim * If the local is being used as a target, mark the local 273efcc2a30SJung-uk Kim * initialized 274efcc2a30SJung-uk Kim */ 275efcc2a30SJung-uk Kim if (Op->Asl.CompileFlags & NODE_IS_TARGET) 276efcc2a30SJung-uk Kim { 277efcc2a30SJung-uk Kim MethodInfo->LocalInitialized[RegisterNumber] = TRUE; 278efcc2a30SJung-uk Kim } 279efcc2a30SJung-uk Kim 280efcc2a30SJung-uk Kim /* 281efcc2a30SJung-uk Kim * Otherwise, this is a reference, check if the local 282efcc2a30SJung-uk Kim * has been previously initialized. 283efcc2a30SJung-uk Kim * 284efcc2a30SJung-uk Kim * The only operator that accepts an uninitialized value is ObjectType() 285efcc2a30SJung-uk Kim */ 286efcc2a30SJung-uk Kim else if ((!MethodInfo->LocalInitialized[RegisterNumber]) && 287efcc2a30SJung-uk Kim (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE)) 288efcc2a30SJung-uk Kim { 289efcc2a30SJung-uk Kim LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30); 290efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName); 291efcc2a30SJung-uk Kim } 292efcc2a30SJung-uk Kim break; 293efcc2a30SJung-uk Kim 294efcc2a30SJung-uk Kim case PARSEOP_ARG0: 295efcc2a30SJung-uk Kim case PARSEOP_ARG1: 296efcc2a30SJung-uk Kim case PARSEOP_ARG2: 297efcc2a30SJung-uk Kim case PARSEOP_ARG3: 298efcc2a30SJung-uk Kim case PARSEOP_ARG4: 299efcc2a30SJung-uk Kim case PARSEOP_ARG5: 300efcc2a30SJung-uk Kim case PARSEOP_ARG6: 301efcc2a30SJung-uk Kim 302efcc2a30SJung-uk Kim if (!MethodInfo) 303efcc2a30SJung-uk Kim { 304efcc2a30SJung-uk Kim /* 305efcc2a30SJung-uk Kim * Arg was used outside a control method, or there was an error 306efcc2a30SJung-uk Kim * in the method declaration. 307efcc2a30SJung-uk Kim */ 308f8146b88SJung-uk Kim AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, 309f8146b88SJung-uk Kim Op, Op->Asl.ExternalName); 310efcc2a30SJung-uk Kim return (AE_ERROR); 311efcc2a30SJung-uk Kim } 312efcc2a30SJung-uk Kim 313efcc2a30SJung-uk Kim RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8; 314efcc2a30SJung-uk Kim ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30); 315efcc2a30SJung-uk Kim 316efcc2a30SJung-uk Kim /* 317efcc2a30SJung-uk Kim * If the Arg is being used as a target, mark the local 318efcc2a30SJung-uk Kim * initialized 319efcc2a30SJung-uk Kim */ 320efcc2a30SJung-uk Kim if (Op->Asl.CompileFlags & NODE_IS_TARGET) 321efcc2a30SJung-uk Kim { 322efcc2a30SJung-uk Kim MethodInfo->ArgInitialized[RegisterNumber] = TRUE; 323efcc2a30SJung-uk Kim } 324efcc2a30SJung-uk Kim 325efcc2a30SJung-uk Kim /* 326efcc2a30SJung-uk Kim * Otherwise, this is a reference, check if the Arg 327efcc2a30SJung-uk Kim * has been previously initialized. 328efcc2a30SJung-uk Kim * 329efcc2a30SJung-uk Kim * The only operator that accepts an uninitialized value is ObjectType() 330efcc2a30SJung-uk Kim */ 331efcc2a30SJung-uk Kim else if ((!MethodInfo->ArgInitialized[RegisterNumber]) && 332efcc2a30SJung-uk Kim (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE)) 333efcc2a30SJung-uk Kim { 334efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName); 335efcc2a30SJung-uk Kim } 336efcc2a30SJung-uk Kim 337efcc2a30SJung-uk Kim /* Flag this arg if it is not a "real" argument to the method */ 338efcc2a30SJung-uk Kim 339efcc2a30SJung-uk Kim if (RegisterNumber >= MethodInfo->NumArguments) 340efcc2a30SJung-uk Kim { 341efcc2a30SJung-uk Kim AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName); 342efcc2a30SJung-uk Kim } 343efcc2a30SJung-uk Kim break; 344efcc2a30SJung-uk Kim 345efcc2a30SJung-uk Kim case PARSEOP_RETURN: 346efcc2a30SJung-uk Kim 347efcc2a30SJung-uk Kim if (!MethodInfo) 348efcc2a30SJung-uk Kim { 349efcc2a30SJung-uk Kim /* 350efcc2a30SJung-uk Kim * Probably was an error in the method declaration, 351efcc2a30SJung-uk Kim * no additional error here 352efcc2a30SJung-uk Kim */ 353efcc2a30SJung-uk Kim ACPI_WARNING ((AE_INFO, "%p, No parent method", Op)); 354efcc2a30SJung-uk Kim return (AE_ERROR); 355efcc2a30SJung-uk Kim } 356efcc2a30SJung-uk Kim 357efcc2a30SJung-uk Kim /* 358efcc2a30SJung-uk Kim * A child indicates a possible return value. A simple Return or 359efcc2a30SJung-uk Kim * Return() is marked with NODE_IS_NULL_RETURN by the parser so 360efcc2a30SJung-uk Kim * that it is not counted as a "real" return-with-value, although 361efcc2a30SJung-uk Kim * the AML code that is actually emitted is Return(0). The AML 362efcc2a30SJung-uk Kim * definition of Return has a required parameter, so we are 363efcc2a30SJung-uk Kim * forced to convert a null return to Return(0). 364efcc2a30SJung-uk Kim */ 365efcc2a30SJung-uk Kim if ((Op->Asl.Child) && 366efcc2a30SJung-uk Kim (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) && 367efcc2a30SJung-uk Kim (!(Op->Asl.Child->Asl.CompileFlags & NODE_IS_NULL_RETURN))) 368efcc2a30SJung-uk Kim { 369efcc2a30SJung-uk Kim MethodInfo->NumReturnWithValue++; 370efcc2a30SJung-uk Kim } 371efcc2a30SJung-uk Kim else 372efcc2a30SJung-uk Kim { 373efcc2a30SJung-uk Kim MethodInfo->NumReturnNoValue++; 374efcc2a30SJung-uk Kim } 375efcc2a30SJung-uk Kim break; 376efcc2a30SJung-uk Kim 377efcc2a30SJung-uk Kim case PARSEOP_BREAK: 378efcc2a30SJung-uk Kim case PARSEOP_CONTINUE: 379efcc2a30SJung-uk Kim 380efcc2a30SJung-uk Kim Next = Op->Asl.Parent; 381efcc2a30SJung-uk Kim while (Next) 382efcc2a30SJung-uk Kim { 383efcc2a30SJung-uk Kim if (Next->Asl.ParseOpcode == PARSEOP_WHILE) 384efcc2a30SJung-uk Kim { 385efcc2a30SJung-uk Kim break; 386efcc2a30SJung-uk Kim } 387efcc2a30SJung-uk Kim Next = Next->Asl.Parent; 388efcc2a30SJung-uk Kim } 389efcc2a30SJung-uk Kim 390efcc2a30SJung-uk Kim if (!Next) 391efcc2a30SJung-uk Kim { 392efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL); 393efcc2a30SJung-uk Kim } 394efcc2a30SJung-uk Kim break; 395efcc2a30SJung-uk Kim 396efcc2a30SJung-uk Kim case PARSEOP_STALL: 397efcc2a30SJung-uk Kim 398efcc2a30SJung-uk Kim /* We can range check if the argument is an integer */ 399efcc2a30SJung-uk Kim 400efcc2a30SJung-uk Kim if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) && 401efcc2a30SJung-uk Kim (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX)) 402efcc2a30SJung-uk Kim { 403efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL); 404efcc2a30SJung-uk Kim } 405efcc2a30SJung-uk Kim break; 406efcc2a30SJung-uk Kim 407efcc2a30SJung-uk Kim case PARSEOP_DEVICE: 408313a0c13SJung-uk Kim 409f8146b88SJung-uk Kim if (!ApFindNameInDeviceTree (METHOD_NAME__HID, Op) && 410f8146b88SJung-uk Kim !ApFindNameInDeviceTree (METHOD_NAME__ADR, Op)) 411313a0c13SJung-uk Kim { 412313a0c13SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_MISSING_DEPENDENCY, Op, 413313a0c13SJung-uk Kim "Device object requires a _HID or _ADR in same scope"); 414313a0c13SJung-uk Kim } 415313a0c13SJung-uk Kim break; 416313a0c13SJung-uk Kim 417efcc2a30SJung-uk Kim case PARSEOP_EVENT: 418efcc2a30SJung-uk Kim case PARSEOP_MUTEX: 419efcc2a30SJung-uk Kim case PARSEOP_OPERATIONREGION: 420efcc2a30SJung-uk Kim case PARSEOP_POWERRESOURCE: 421efcc2a30SJung-uk Kim case PARSEOP_PROCESSOR: 422efcc2a30SJung-uk Kim case PARSEOP_THERMALZONE: 423efcc2a30SJung-uk Kim 424efcc2a30SJung-uk Kim /* 425efcc2a30SJung-uk Kim * The first operand is a name to be created in the namespace. 426efcc2a30SJung-uk Kim * Check against the reserved list. 427efcc2a30SJung-uk Kim */ 428efcc2a30SJung-uk Kim i = ApCheckForPredefinedName (Op, Op->Asl.NameSeg); 429efcc2a30SJung-uk Kim if (i < ACPI_VALID_RESERVED_NAME_MAX) 430efcc2a30SJung-uk Kim { 431f8146b88SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, 432f8146b88SJung-uk Kim Op, Op->Asl.ExternalName); 433efcc2a30SJung-uk Kim } 434efcc2a30SJung-uk Kim break; 435efcc2a30SJung-uk Kim 436efcc2a30SJung-uk Kim case PARSEOP_NAME: 437efcc2a30SJung-uk Kim 438efcc2a30SJung-uk Kim /* Typecheck any predefined names statically defined with Name() */ 439efcc2a30SJung-uk Kim 440efcc2a30SJung-uk Kim ApCheckForPredefinedObject (Op, Op->Asl.NameSeg); 441efcc2a30SJung-uk Kim 442efcc2a30SJung-uk Kim /* Special typechecking for _HID */ 443efcc2a30SJung-uk Kim 4445ef50723SJung-uk Kim if (!strcmp (METHOD_NAME__HID, Op->Asl.NameSeg)) 445efcc2a30SJung-uk Kim { 446efcc2a30SJung-uk Kim Next = Op->Asl.Child->Asl.Next; 447efcc2a30SJung-uk Kim AnCheckId (Next, ASL_TYPE_HID); 448efcc2a30SJung-uk Kim } 449efcc2a30SJung-uk Kim 450efcc2a30SJung-uk Kim /* Special typechecking for _CID */ 451efcc2a30SJung-uk Kim 4525ef50723SJung-uk Kim else if (!strcmp (METHOD_NAME__CID, Op->Asl.NameSeg)) 453efcc2a30SJung-uk Kim { 454efcc2a30SJung-uk Kim Next = Op->Asl.Child->Asl.Next; 455efcc2a30SJung-uk Kim 456efcc2a30SJung-uk Kim if ((Next->Asl.ParseOpcode == PARSEOP_PACKAGE) || 457efcc2a30SJung-uk Kim (Next->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)) 458efcc2a30SJung-uk Kim { 459efcc2a30SJung-uk Kim Next = Next->Asl.Child; 460efcc2a30SJung-uk Kim while (Next) 461efcc2a30SJung-uk Kim { 462efcc2a30SJung-uk Kim AnCheckId (Next, ASL_TYPE_CID); 463efcc2a30SJung-uk Kim Next = Next->Asl.Next; 464efcc2a30SJung-uk Kim } 465efcc2a30SJung-uk Kim } 466efcc2a30SJung-uk Kim else 467efcc2a30SJung-uk Kim { 468efcc2a30SJung-uk Kim AnCheckId (Next, ASL_TYPE_CID); 469efcc2a30SJung-uk Kim } 470efcc2a30SJung-uk Kim } 471313a0c13SJung-uk Kim 472efcc2a30SJung-uk Kim break; 473efcc2a30SJung-uk Kim 474efcc2a30SJung-uk Kim default: 475a9d8d09cSJung-uk Kim 476efcc2a30SJung-uk Kim break; 477efcc2a30SJung-uk Kim } 478efcc2a30SJung-uk Kim 479a9d8d09cSJung-uk Kim /* Check for named object creation within a non-serialized method */ 480a9d8d09cSJung-uk Kim 481a9d8d09cSJung-uk Kim MtCheckNamedObjectInMethod (Op, MethodInfo); 482efcc2a30SJung-uk Kim return (AE_OK); 483efcc2a30SJung-uk Kim } 484efcc2a30SJung-uk Kim 485efcc2a30SJung-uk Kim 486efcc2a30SJung-uk Kim /******************************************************************************* 487efcc2a30SJung-uk Kim * 488a9d8d09cSJung-uk Kim * FUNCTION: MtCheckNamedObjectInMethod 489a9d8d09cSJung-uk Kim * 490a9d8d09cSJung-uk Kim * PARAMETERS: Op - Current parser op 491a9d8d09cSJung-uk Kim * MethodInfo - Info for method being parsed 492a9d8d09cSJung-uk Kim * 493a9d8d09cSJung-uk Kim * RETURN: None 494a9d8d09cSJung-uk Kim * 495a9d8d09cSJung-uk Kim * DESCRIPTION: Detect if a non-serialized method is creating a named object, 496a9d8d09cSJung-uk Kim * which could possibly cause problems if two threads execute 497a9d8d09cSJung-uk Kim * the method concurrently. Emit a remark in this case. 498a9d8d09cSJung-uk Kim * 499a9d8d09cSJung-uk Kim ******************************************************************************/ 500a9d8d09cSJung-uk Kim 501f8146b88SJung-uk Kim static void 502a9d8d09cSJung-uk Kim MtCheckNamedObjectInMethod ( 503a9d8d09cSJung-uk Kim ACPI_PARSE_OBJECT *Op, 504a9d8d09cSJung-uk Kim ASL_METHOD_INFO *MethodInfo) 505a9d8d09cSJung-uk Kim { 506a9d8d09cSJung-uk Kim const ACPI_OPCODE_INFO *OpInfo; 507a9d8d09cSJung-uk Kim 508a9d8d09cSJung-uk Kim 509f8146b88SJung-uk Kim /* We don't care about actual method declarations or scopes */ 510a9d8d09cSJung-uk Kim 511f8146b88SJung-uk Kim if ((Op->Asl.AmlOpcode == AML_METHOD_OP) || 512f8146b88SJung-uk Kim (Op->Asl.AmlOpcode == AML_SCOPE_OP)) 513a9d8d09cSJung-uk Kim { 514a9d8d09cSJung-uk Kim return; 515a9d8d09cSJung-uk Kim } 516a9d8d09cSJung-uk Kim 517a9d8d09cSJung-uk Kim /* Determine if we are creating a named object */ 518a9d8d09cSJung-uk Kim 519a9d8d09cSJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 520a9d8d09cSJung-uk Kim if (OpInfo->Class == AML_CLASS_NAMED_OBJECT) 521a9d8d09cSJung-uk Kim { 522a9d8d09cSJung-uk Kim /* 523a9d8d09cSJung-uk Kim * If we have a named object created within a non-serialized method, 524a9d8d09cSJung-uk Kim * emit a remark that the method should be serialized. 525a9d8d09cSJung-uk Kim * 526a9d8d09cSJung-uk Kim * Reason: If a thread blocks within the method for any reason, and 527a9d8d09cSJung-uk Kim * another thread enters the method, the method will fail because an 528a9d8d09cSJung-uk Kim * attempt will be made to create the same object twice. 529a9d8d09cSJung-uk Kim */ 530a9d8d09cSJung-uk Kim if (MethodInfo && !MethodInfo->ShouldBeSerialized) 531a9d8d09cSJung-uk Kim { 532a9d8d09cSJung-uk Kim AslError (ASL_REMARK, ASL_MSG_SERIALIZED_REQUIRED, MethodInfo->Op, 533a9d8d09cSJung-uk Kim "due to creation of named objects within"); 534a9d8d09cSJung-uk Kim 535a9d8d09cSJung-uk Kim /* Emit message only ONCE per method */ 536a9d8d09cSJung-uk Kim 537a9d8d09cSJung-uk Kim MethodInfo->ShouldBeSerialized = TRUE; 538a9d8d09cSJung-uk Kim } 539a9d8d09cSJung-uk Kim } 540a9d8d09cSJung-uk Kim } 541a9d8d09cSJung-uk Kim 542a9d8d09cSJung-uk Kim 543a9d8d09cSJung-uk Kim /******************************************************************************* 544a9d8d09cSJung-uk Kim * 545efcc2a30SJung-uk Kim * FUNCTION: MtMethodAnalysisWalkEnd 546efcc2a30SJung-uk Kim * 547efcc2a30SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 548efcc2a30SJung-uk Kim * 549efcc2a30SJung-uk Kim * RETURN: Status 550efcc2a30SJung-uk Kim * 551efcc2a30SJung-uk Kim * DESCRIPTION: Ascending callback for analysis walk. Complete method 552efcc2a30SJung-uk Kim * return analysis. 553efcc2a30SJung-uk Kim * 554efcc2a30SJung-uk Kim ******************************************************************************/ 555efcc2a30SJung-uk Kim 556efcc2a30SJung-uk Kim ACPI_STATUS 557efcc2a30SJung-uk Kim MtMethodAnalysisWalkEnd ( 558efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *Op, 559efcc2a30SJung-uk Kim UINT32 Level, 560efcc2a30SJung-uk Kim void *Context) 561efcc2a30SJung-uk Kim { 562efcc2a30SJung-uk Kim ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context; 563efcc2a30SJung-uk Kim ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack; 564efcc2a30SJung-uk Kim 565efcc2a30SJung-uk Kim 566efcc2a30SJung-uk Kim switch (Op->Asl.ParseOpcode) 567efcc2a30SJung-uk Kim { 568efcc2a30SJung-uk Kim case PARSEOP_METHOD: 569efcc2a30SJung-uk Kim case PARSEOP_RETURN: 570a9d8d09cSJung-uk Kim 571efcc2a30SJung-uk Kim if (!MethodInfo) 572efcc2a30SJung-uk Kim { 573efcc2a30SJung-uk Kim printf ("No method info for method! [%s]\n", Op->Asl.Namepath); 574efcc2a30SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, 575efcc2a30SJung-uk Kim "No method info for this method"); 576efcc2a30SJung-uk Kim 577efcc2a30SJung-uk Kim CmCleanupAndExit (); 578efcc2a30SJung-uk Kim return (AE_AML_INTERNAL); 579efcc2a30SJung-uk Kim } 580efcc2a30SJung-uk Kim break; 581efcc2a30SJung-uk Kim 582efcc2a30SJung-uk Kim default: 583a9d8d09cSJung-uk Kim 584efcc2a30SJung-uk Kim break; 585efcc2a30SJung-uk Kim } 586efcc2a30SJung-uk Kim 587efcc2a30SJung-uk Kim switch (Op->Asl.ParseOpcode) 588efcc2a30SJung-uk Kim { 589efcc2a30SJung-uk Kim case PARSEOP_METHOD: 590efcc2a30SJung-uk Kim 591efcc2a30SJung-uk Kim WalkInfo->MethodStack = MethodInfo->Next; 592efcc2a30SJung-uk Kim 593efcc2a30SJung-uk Kim /* 594efcc2a30SJung-uk Kim * Check if there is no return statement at the end of the 595efcc2a30SJung-uk Kim * method AND we can actually get there -- i.e., the execution 596efcc2a30SJung-uk Kim * of the method can possibly terminate without a return statement. 597efcc2a30SJung-uk Kim */ 598efcc2a30SJung-uk Kim if ((!AnLastStatementIsReturn (Op)) && 599efcc2a30SJung-uk Kim (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT))) 600efcc2a30SJung-uk Kim { 601efcc2a30SJung-uk Kim /* 602efcc2a30SJung-uk Kim * No return statement, and execution can possibly exit 603efcc2a30SJung-uk Kim * via this path. This is equivalent to Return () 604efcc2a30SJung-uk Kim */ 605efcc2a30SJung-uk Kim MethodInfo->NumReturnNoValue++; 606efcc2a30SJung-uk Kim } 607efcc2a30SJung-uk Kim 608efcc2a30SJung-uk Kim /* 609efcc2a30SJung-uk Kim * Check for case where some return statements have a return value 610efcc2a30SJung-uk Kim * and some do not. Exit without a return statement is a return with 611efcc2a30SJung-uk Kim * no value 612efcc2a30SJung-uk Kim */ 613efcc2a30SJung-uk Kim if (MethodInfo->NumReturnNoValue && 614efcc2a30SJung-uk Kim MethodInfo->NumReturnWithValue) 615efcc2a30SJung-uk Kim { 616efcc2a30SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op, 617efcc2a30SJung-uk Kim Op->Asl.ExternalName); 618efcc2a30SJung-uk Kim } 619efcc2a30SJung-uk Kim 620efcc2a30SJung-uk Kim /* 621efcc2a30SJung-uk Kim * If there are any RETURN() statements with no value, or there is a 622efcc2a30SJung-uk Kim * control path that allows the method to exit without a return value, 623efcc2a30SJung-uk Kim * we mark the method as a method that does not return a value. This 624efcc2a30SJung-uk Kim * knowledge can be used to check method invocations that expect a 625efcc2a30SJung-uk Kim * returned value. 626efcc2a30SJung-uk Kim */ 627efcc2a30SJung-uk Kim if (MethodInfo->NumReturnNoValue) 628efcc2a30SJung-uk Kim { 629efcc2a30SJung-uk Kim if (MethodInfo->NumReturnWithValue) 630efcc2a30SJung-uk Kim { 631efcc2a30SJung-uk Kim Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL; 632efcc2a30SJung-uk Kim } 633efcc2a30SJung-uk Kim else 634efcc2a30SJung-uk Kim { 635efcc2a30SJung-uk Kim Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL; 636efcc2a30SJung-uk Kim } 637efcc2a30SJung-uk Kim } 638efcc2a30SJung-uk Kim 639efcc2a30SJung-uk Kim /* 640efcc2a30SJung-uk Kim * Check predefined method names for correct return behavior 641efcc2a30SJung-uk Kim * and correct number of arguments. Also, some special checks 642efcc2a30SJung-uk Kim * For GPE and _REG methods. 643efcc2a30SJung-uk Kim */ 644efcc2a30SJung-uk Kim if (ApCheckForPredefinedMethod (Op, MethodInfo)) 645efcc2a30SJung-uk Kim { 646efcc2a30SJung-uk Kim /* Special check for two names like _L01 and _E01 in same scope */ 647efcc2a30SJung-uk Kim 648efcc2a30SJung-uk Kim ApCheckForGpeNameConflict (Op); 649efcc2a30SJung-uk Kim 650efcc2a30SJung-uk Kim /* 651efcc2a30SJung-uk Kim * Special check for _REG: Must have an operation region definition 652efcc2a30SJung-uk Kim * within the same scope! 653efcc2a30SJung-uk Kim */ 654efcc2a30SJung-uk Kim ApCheckRegMethod (Op); 655efcc2a30SJung-uk Kim } 656efcc2a30SJung-uk Kim 657efcc2a30SJung-uk Kim ACPI_FREE (MethodInfo); 658efcc2a30SJung-uk Kim break; 659efcc2a30SJung-uk Kim 660efcc2a30SJung-uk Kim case PARSEOP_NAME: 661efcc2a30SJung-uk Kim 662efcc2a30SJung-uk Kim /* Special check for two names like _L01 and _E01 in same scope */ 663efcc2a30SJung-uk Kim 664efcc2a30SJung-uk Kim ApCheckForGpeNameConflict (Op); 665efcc2a30SJung-uk Kim break; 666efcc2a30SJung-uk Kim 667efcc2a30SJung-uk Kim case PARSEOP_RETURN: 668efcc2a30SJung-uk Kim 669efcc2a30SJung-uk Kim /* 670efcc2a30SJung-uk Kim * If the parent is a predefined method name, attempt to typecheck 671efcc2a30SJung-uk Kim * the return value. Only static types can be validated. 672efcc2a30SJung-uk Kim */ 673efcc2a30SJung-uk Kim ApCheckPredefinedReturnValue (Op, MethodInfo); 674efcc2a30SJung-uk Kim 675efcc2a30SJung-uk Kim /* 676efcc2a30SJung-uk Kim * The parent block does not "exit" and continue execution -- the 677efcc2a30SJung-uk Kim * method is terminated here with the Return() statement. 678efcc2a30SJung-uk Kim */ 679efcc2a30SJung-uk Kim Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 680efcc2a30SJung-uk Kim 681efcc2a30SJung-uk Kim /* Used in the "typing" pass later */ 682efcc2a30SJung-uk Kim 683efcc2a30SJung-uk Kim Op->Asl.ParentMethod = MethodInfo->Op; 684efcc2a30SJung-uk Kim 685efcc2a30SJung-uk Kim /* 686efcc2a30SJung-uk Kim * If there is a peer node after the return statement, then this 687efcc2a30SJung-uk Kim * node is unreachable code -- i.e., it won't be executed because of 688efcc2a30SJung-uk Kim * the preceding Return() statement. 689efcc2a30SJung-uk Kim */ 690efcc2a30SJung-uk Kim if (Op->Asl.Next) 691efcc2a30SJung-uk Kim { 692f8146b88SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, 693f8146b88SJung-uk Kim Op->Asl.Next, NULL); 694efcc2a30SJung-uk Kim } 695efcc2a30SJung-uk Kim break; 696efcc2a30SJung-uk Kim 697efcc2a30SJung-uk Kim case PARSEOP_IF: 698efcc2a30SJung-uk Kim 699efcc2a30SJung-uk Kim if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 700efcc2a30SJung-uk Kim (Op->Asl.Next) && 701efcc2a30SJung-uk Kim (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE)) 702efcc2a30SJung-uk Kim { 703efcc2a30SJung-uk Kim /* 704efcc2a30SJung-uk Kim * This IF has a corresponding ELSE. The IF block has no exit, 705efcc2a30SJung-uk Kim * (it contains an unconditional Return) 706efcc2a30SJung-uk Kim * mark the ELSE block to remember this fact. 707efcc2a30SJung-uk Kim */ 708efcc2a30SJung-uk Kim Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT; 709efcc2a30SJung-uk Kim } 710efcc2a30SJung-uk Kim break; 711efcc2a30SJung-uk Kim 712efcc2a30SJung-uk Kim case PARSEOP_ELSE: 713efcc2a30SJung-uk Kim 714efcc2a30SJung-uk Kim if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 715efcc2a30SJung-uk Kim (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT)) 716efcc2a30SJung-uk Kim { 717efcc2a30SJung-uk Kim /* 718efcc2a30SJung-uk Kim * This ELSE block has no exit and the corresponding IF block 719efcc2a30SJung-uk Kim * has no exit either. Therefore, the parent node has no exit. 720efcc2a30SJung-uk Kim */ 721efcc2a30SJung-uk Kim Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 722efcc2a30SJung-uk Kim } 723efcc2a30SJung-uk Kim break; 724efcc2a30SJung-uk Kim 725efcc2a30SJung-uk Kim 726efcc2a30SJung-uk Kim default: 727efcc2a30SJung-uk Kim 728efcc2a30SJung-uk Kim if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 729efcc2a30SJung-uk Kim (Op->Asl.Parent)) 730efcc2a30SJung-uk Kim { 731efcc2a30SJung-uk Kim /* If this node has no exit, then the parent has no exit either */ 732efcc2a30SJung-uk Kim 733efcc2a30SJung-uk Kim Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 734efcc2a30SJung-uk Kim } 735efcc2a30SJung-uk Kim break; 736efcc2a30SJung-uk Kim } 737efcc2a30SJung-uk Kim 738efcc2a30SJung-uk Kim return (AE_OK); 739efcc2a30SJung-uk Kim } 740