LCOV - code coverage report
Current view: top level - /mnt/build/buildbot/bld/build-lcov/gcc/m2/gm2-compiler-boot - M2CaseList.c (source / functions) Coverage Total Hit
Test: gcc.info Lines: 90.2 % 615 555
Test Date: 2026-02-28 14:20:25 Functions: 95.6 % 45 43
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* do not edit automatically generated by mc from M2CaseList.  */
       2              : /* M2CaseList.mod implement ISO case label lists.
       3              : 
       4              : Copyright (C) 2009-2026 Free Software Foundation, Inc.
       5              : Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
       6              : 
       7              : This file is part of GNU Modula-2.
       8              : 
       9              : GNU Modula-2 is free software; you can redistribute it and/or modify
      10              : it under the terms of the GNU General Public License as published by
      11              : the Free Software Foundation; either version 3, or (at your option)
      12              : any later version.
      13              : 
      14              : GNU Modula-2 is distributed in the hope that it will be useful, but
      15              : WITHOUT ANY WARRANTY; without even the implied warranty of
      16              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17              : General Public License for more details.
      18              : 
      19              : You should have received a copy of the GNU General Public License
      20              : along with GNU Modula-2; see the file COPYING3.  If not see
      21              : <http://www.gnu.org/licenses/>.  */
      22              : 
      23              : #include "config.h"
      24              : #include "system.h"
      25              : #include "gcc-consolidation.h"
      26              : 
      27              : #include <stdbool.h>
      28              : #   if !defined (PROC_D)
      29              : #      define PROC_D
      30              :        typedef void (*PROC_t) (void);
      31              :        typedef struct { PROC_t proc; } PROC;
      32              : #   endif
      33              : 
      34              : #   if !defined (TRUE)
      35              : #      define TRUE (1==1)
      36              : #   endif
      37              : 
      38              : #   if !defined (FALSE)
      39              : #      define FALSE (1==0)
      40              : #   endif
      41              : 
      42              : #   include "GStorage.h"
      43              : #if defined(__cplusplus)
      44              : #   undef NULL
      45              : #   define NULL 0
      46              : #endif
      47              : #define _M2CaseList_C
      48              : 
      49              : #include "GM2CaseList.h"
      50              : #   include "GM2Debug.h"
      51              : #   include "GM2GCCDeclare.h"
      52              : #   include "GM2MetaError.h"
      53              : #   include "GM2Error.h"
      54              : #   include "GM2Range.h"
      55              : #   include "GM2ALU.h"
      56              : #   include "GIndexing.h"
      57              : #   include "GLists.h"
      58              : #   include "GNameKey.h"
      59              : #   include "GSymbolConversion.h"
      60              : #   include "GDynamicStrings.h"
      61              : #   include "Ggcctypes.h"
      62              : #   include "Gm2block.h"
      63              : #   include "Gm2type.h"
      64              : #   include "Gm2expr.h"
      65              : #   include "GStorage.h"
      66              : #   include "GM2Base.h"
      67              : #   include "GM2LexBuf.h"
      68              : #   include "GNumberIO.h"
      69              : #   include "GSymbolTable.h"
      70              : 
      71              : typedef struct M2CaseList__T1_r M2CaseList__T1;
      72              : 
      73              : typedef M2CaseList__T1 *M2CaseList_RangePair;
      74              : 
      75              : typedef struct M2CaseList__T2_r M2CaseList__T2;
      76              : 
      77              : typedef M2CaseList__T2 *M2CaseList_ConflictingPair;
      78              : 
      79              : typedef struct M2CaseList__T3_r M2CaseList__T3;
      80              : 
      81              : typedef M2CaseList__T3 *M2CaseList_CaseList;
      82              : 
      83              : typedef struct M2CaseList__T4_r M2CaseList__T4;
      84              : 
      85              : typedef M2CaseList__T4 *M2CaseList_CaseDescriptor;
      86              : 
      87              : typedef struct M2CaseList__T5_r M2CaseList__T5;
      88              : 
      89              : typedef M2CaseList__T5 *M2CaseList_SetRange;
      90              : 
      91              : struct M2CaseList__T1_r {
      92              :                           unsigned int low;
      93              :                           unsigned int high;
      94              :                           unsigned int tokenno;
      95              :                         };
      96              : 
      97              : struct M2CaseList__T2_r {
      98              :                           M2CaseList_RangePair a;
      99              :                           M2CaseList_RangePair b;
     100              :                         };
     101              : 
     102              : struct M2CaseList__T3_r {
     103              :                           unsigned int maxRangeId;
     104              :                           Indexing_Index rangeArray;
     105              :                           M2CaseList_RangePair currentRange;
     106              :                           unsigned int varientField;
     107              :                         };
     108              : 
     109              : struct M2CaseList__T4_r {
     110              :                           bool resolved;
     111              :                           bool elseClause;
     112              :                           unsigned int elseField;
     113              :                           unsigned int record;
     114              :                           unsigned int varient;
     115              :                           unsigned int expression;
     116              :                           unsigned int maxCaseId;
     117              :                           Indexing_Index caseListArray;
     118              :                           M2CaseList_CaseList currentCase;
     119              :                           M2CaseList_CaseDescriptor next;
     120              :                         };
     121              : 
     122              : struct M2CaseList__T5_r {
     123              :                           tree low;
     124              :                           tree high;
     125              :                           M2CaseList_SetRange next;
     126              :                         };
     127              : 
     128              : static M2CaseList_CaseDescriptor caseStack;
     129              : static unsigned int caseId;
     130              : static Indexing_Index caseArray;
     131              : static Indexing_Index conflictArray;
     132              : static M2CaseList_SetRange FreeRangeList;
     133              : static DynamicStrings_String errorString;
     134              : 
     135              : /*
     136              :    PushCase - create a case entity and push it to an internal stack.
     137              :               rec is NulSym if this is a CASE statement.
     138              :               If rec is a record then it indicates a possible
     139              :               varients reside in the record to check.
     140              :               Both rec and va might be NulSym and then the expr
     141              :               will contain the selector expression to a case statement.
     142              :               Return the case id.
     143              : */
     144              : 
     145              : extern "C" unsigned int M2CaseList_PushCase (unsigned int rec, unsigned int va, unsigned int expr);
     146              : 
     147              : /*
     148              :    PopCase - pop the top element of the case entity from the internal
     149              :              stack.
     150              : */
     151              : 
     152              : extern "C" void M2CaseList_PopCase (void);
     153              : 
     154              : /*
     155              :    ElseCase - indicates that this case varient does have an else clause.
     156              : */
     157              : 
     158              : extern "C" void M2CaseList_ElseCase (unsigned int f);
     159              : 
     160              : /*
     161              :    BeginCaseList - create a new label list.
     162              : */
     163              : 
     164              : extern "C" void M2CaseList_BeginCaseList (unsigned int v);
     165              : 
     166              : /*
     167              :    EndCaseList - terminate the current label list.
     168              : */
     169              : 
     170              : extern "C" void M2CaseList_EndCaseList (void);
     171              : 
     172              : /*
     173              :    AddRange - add a range to the current label list.
     174              : */
     175              : 
     176              : extern "C" void M2CaseList_AddRange (unsigned int r1, unsigned int r2, unsigned int tok);
     177              : 
     178              : /*
     179              :    CaseBoundsResolved - returns TRUE if all constants in the case list, c,
     180              :                         are known to GCC.
     181              : */
     182              : 
     183              : extern "C" bool M2CaseList_CaseBoundsResolved (unsigned int tokenno, unsigned int c);
     184              : 
     185              : /*
     186              :    TypeCaseBounds - returns true if all bounds in case list, c, are
     187              :                     compatible with the tagged type.
     188              : */
     189              : 
     190              : extern "C" bool M2CaseList_TypeCaseBounds (unsigned int c);
     191              : 
     192              : /*
     193              :    OverlappingCaseBounds - returns TRUE if there were any overlapping bounds
     194              :                            in the case list, c.  It will generate an error
     195              :                            messages for each overlapping bound found.
     196              : */
     197              : 
     198              : extern "C" bool M2CaseList_OverlappingCaseBounds (unsigned int c);
     199              : 
     200              : /*
     201              :    MissingCaseBounds - returns true if there were any missing bounds
     202              :                        in the varient record case list, c.  It will
     203              :                        generate an error message for each missing
     204              :                        bounds found.
     205              : */
     206              : 
     207              : extern "C" bool M2CaseList_MissingCaseBounds (unsigned int tokenno, unsigned int c);
     208              : 
     209              : /*
     210              :    MissingCaseStatementBounds - returns true if the case statement has a missing
     211              :                                 clause.  It will also generate error messages.
     212              : */
     213              : 
     214              : extern "C" bool M2CaseList_MissingCaseStatementBounds (unsigned int tokenno, unsigned int c);
     215              : 
     216              : /*
     217              :    WriteCase - dump out the case list (internal debugging).
     218              : */
     219              : 
     220              : extern "C" void M2CaseList_WriteCase (unsigned int c);
     221              : 
     222              : /*
     223              :    GetVariantTagType - returns the type associated with, variant.
     224              : */
     225              : 
     226              : static unsigned int GetVariantTagType (unsigned int variant);
     227              : 
     228              : /*
     229              :    CheckCaseBoundsResolved - return TRUE if all constants in the case list c are known to GCC.
     230              : */
     231              : 
     232              : static bool CheckCaseBoundsResolved (unsigned int tokenno, unsigned int c);
     233              : 
     234              : /*
     235              :    ConvertNulStr2NulChar -
     236              : */
     237              : 
     238              : static void ConvertNulStr2NulChar (unsigned int tokenno, unsigned int c);
     239              : 
     240              : /*
     241              :    NulStr2NulChar - if sym is a const string of length 0 then return
     242              :                     a nul char instead otherwise return sym.
     243              : */
     244              : 
     245              : static unsigned int NulStr2NulChar (unsigned int tok, unsigned int sym);
     246              : 
     247              : /*
     248              :    IsSame - return TRUE if r, s, are in, e.
     249              : */
     250              : 
     251              : static bool IsSame (M2CaseList_ConflictingPair e, M2CaseList_RangePair r, M2CaseList_RangePair s);
     252              : 
     253              : /*
     254              :    SeenBefore -
     255              : */
     256              : 
     257              : static bool SeenBefore (M2CaseList_RangePair r, M2CaseList_RangePair s);
     258              : 
     259              : /*
     260              :    Overlaps -
     261              : */
     262              : 
     263              : static bool Overlaps (M2CaseList_RangePair r, M2CaseList_RangePair s);
     264              : 
     265              : /*
     266              :    GetCaseExpression - return the type from the expression.
     267              : */
     268              : 
     269              : static unsigned int GetCaseExpression (M2CaseList_CaseDescriptor p);
     270              : 
     271              : /*
     272              :    OverlappingCaseBound - returns TRUE if, r, overlaps any case bound in the
     273              :                           case statement, c.
     274              : */
     275              : 
     276              : static bool OverlappingCaseBound (M2CaseList_RangePair r, unsigned int c);
     277              : 
     278              : /*
     279              :    NewRanges - return a new range from the freelist or heap.
     280              : */
     281              : 
     282              : static M2CaseList_SetRange NewRanges (void);
     283              : 
     284              : /*
     285              :    NewSet - returns a new set based on type with the low and high fields assigned
     286              :             to the min and max values for the type.
     287              : */
     288              : 
     289              : static M2CaseList_SetRange NewSet (unsigned int type);
     290              : 
     291              : /*
     292              :    DisposeRanges - place set and its list onto the free list.
     293              : */
     294              : 
     295              : static M2CaseList_SetRange DisposeRanges (M2CaseList_SetRange set);
     296              : 
     297              : /*
     298              :    RemoveRange - removes the range descriptor h from set and return the
     299              :                  possibly new head of set.
     300              : */
     301              : 
     302              : static M2CaseList_SetRange RemoveRange (M2CaseList_SetRange set, M2CaseList_SetRange h);
     303              : 
     304              : /*
     305              :    SubBitRange - subtracts bits, lo..hi, from, set.
     306              : */
     307              : 
     308              : static M2CaseList_SetRange SubBitRange (M2CaseList_SetRange set, tree lo, tree hi, unsigned int tokenno);
     309              : 
     310              : /*
     311              :    CheckLowHigh - checks to see the low value <= high value and issues an error
     312              :                   if this is not true.
     313              : */
     314              : 
     315              : static void CheckLowHigh (M2CaseList_RangePair rp);
     316              : 
     317              : /*
     318              :    ExcludeCaseRanges - excludes all case ranges found in, p, from, set
     319              : */
     320              : 
     321              : static M2CaseList_SetRange ExcludeCaseRanges (M2CaseList_SetRange set, M2CaseList_CaseDescriptor cd);
     322              : 
     323              : /*
     324              :    IncludeElement - only include enumeration field into errorString if it lies between low..high.
     325              : */
     326              : 
     327              : static void IncludeElement (Lists_List enumList, unsigned int field, tree low, tree high);
     328              : 
     329              : /*
     330              :    IncludeElements - only include enumeration field values low..high in errorString.
     331              : */
     332              : 
     333              : static void IncludeElements (unsigned int type, Lists_List enumList, tree low, tree high);
     334              : 
     335              : /*
     336              :    ErrorRangeEnum - include enumeration fields Low to High in errorString.
     337              : */
     338              : 
     339              : static void ErrorRangeEnum (unsigned int type, M2CaseList_SetRange set, Lists_List enumList);
     340              : 
     341              : /*
     342              :    ErrorRanges - return a list of all enumeration fields not present in the case statement.
     343              :                  The return value will be nil if type is not an enumeration type.
     344              : */
     345              : 
     346              : static Lists_List ErrorRanges (unsigned int type, M2CaseList_SetRange set);
     347              : 
     348              : /*
     349              :    appendString - appends str to errorString.
     350              : */
     351              : 
     352              : static void appendString (DynamicStrings_String str);
     353              : 
     354              : /*
     355              :    appendEnum - appends enum to errorString.
     356              : */
     357              : 
     358              : static void appendEnum (unsigned int enum_);
     359              : 
     360              : /*
     361              :    appendStr - appends str to errorString.
     362              : */
     363              : 
     364              : static void appendStr (const char *str_, unsigned int _str_high);
     365              : 
     366              : /*
     367              :    EnumerateErrors - populate errorString with the contents of enumList.
     368              : */
     369              : 
     370              : static void EnumerateErrors (Lists_List enumList);
     371              : 
     372              : /*
     373              :    NoOfSetElements - return the number of set elements.
     374              : */
     375              : 
     376              : static tree NoOfSetElements (M2CaseList_SetRange set);
     377              : 
     378              : /*
     379              :    isPrintableChar - a cautious isprint.
     380              : */
     381              : 
     382              : static bool isPrintableChar (tree value);
     383              : 
     384              : /*
     385              :    appendTree - append tree value to the errorString.  It attempts to pretty print
     386              :                 CHAR constants and will fall back to CHR (x) if necessary.
     387              : */
     388              : 
     389              : static void appendTree (tree value, unsigned int type);
     390              : 
     391              : /*
     392              :    SubrangeErrors - create an errorString containing all set ranges.
     393              : */
     394              : 
     395              : static void SubrangeErrors (unsigned int subrangetype, M2CaseList_SetRange set);
     396              : 
     397              : /*
     398              :    EmitMissingRangeErrors - emits a singular/plural error message for an enumeration type.
     399              : */
     400              : 
     401              : static void EmitMissingRangeErrors (unsigned int tokenno, unsigned int type, M2CaseList_SetRange set);
     402              : 
     403              : /*
     404              :    checkTypes - checks to see that, constant, and, type, are compatible.
     405              : */
     406              : 
     407              : static bool checkTypes (unsigned int constant, unsigned int type);
     408              : 
     409              : /*
     410              :    inRange - returns true if, min <= i <= max.
     411              : */
     412              : 
     413              : static bool inRange (unsigned int i, unsigned int min, unsigned int max);
     414              : 
     415              : 
     416              : /*
     417              :    GetVariantTagType - returns the type associated with, variant.
     418              : */
     419              : 
     420        12750 : static unsigned int GetVariantTagType (unsigned int variant)
     421              : {
     422        12750 :   unsigned int tag;
     423              : 
     424        12750 :   tag = SymbolTable_GetVarientTag (variant);
     425        12750 :   if ((SymbolTable_IsFieldVarient (tag)) || (SymbolTable_IsRecordField (tag)))
     426              :     {
     427        12726 :       return SymbolTable_GetType (tag);
     428              :     }
     429              :   else
     430              :     {
     431              :       return tag;
     432              :     }
     433              :   /* static analysis guarentees a RETURN statement will be used before here.  */
     434              :   __builtin_unreachable ();
     435              : }
     436              : 
     437              : 
     438              : /*
     439              :    CheckCaseBoundsResolved - return TRUE if all constants in the case list c are known to GCC.
     440              : */
     441              : 
     442         9676 : static bool CheckCaseBoundsResolved (unsigned int tokenno, unsigned int c)
     443              : {
     444         9676 :   M2CaseList_CaseDescriptor p;
     445         9676 :   M2CaseList_CaseList q;
     446         9676 :   M2CaseList_RangePair r;
     447         9676 :   unsigned int min;
     448         9676 :   unsigned int max;
     449         9676 :   unsigned int type;
     450         9676 :   unsigned int i;
     451         9676 :   unsigned int j;
     452              : 
     453         9676 :   p = static_cast<M2CaseList_CaseDescriptor> (Indexing_GetIndice (caseArray, c));
     454         9676 :   if (p->varient != SymbolTable_NulSym)
     455              :     {
     456              :       /* not a CASE statement, but a varient record containing without an ELSE clause  */
     457         8616 :       type = GetVariantTagType (p->varient);
     458         8616 :       p->resolved = true;
     459         8616 :       if (! (SymbolConversion_GccKnowsAbout (type)))
     460              :         {
     461              :           /* do we need to add, type, to the list of types required to be resolved?  */
     462         5538 :           p->resolved = false;
     463              :         }
     464         8616 :       min = M2GCCDeclare_GetTypeMin (type);
     465         8616 :       if (! (SymbolConversion_GccKnowsAbout (min)))
     466              :         {
     467         5628 :           M2GCCDeclare_TryDeclareConstant (tokenno, min);
     468         5628 :           p->resolved = false;
     469              :         }
     470         8616 :       max = M2GCCDeclare_GetTypeMax (type);
     471         8616 :       if (! (SymbolConversion_GccKnowsAbout (max)))
     472              :         {
     473         5628 :           M2GCCDeclare_TryDeclareConstant (tokenno, max);
     474         5628 :           p->resolved = false;
     475              :         }
     476         8616 :       if (! p->resolved)
     477              :         {
     478              :           return false;
     479              :         }
     480              :     }
     481              :   i = 1;
     482        13730 :   while (i <= p->maxCaseId)
     483              :     {
     484         9766 :       q = static_cast<M2CaseList_CaseList> (Indexing_GetIndice (p->caseListArray, i));
     485         9766 :       j = 1;
     486        29306 :       while (j <= q->maxRangeId)
     487              :         {
     488         9858 :           r = static_cast<M2CaseList_RangePair> (Indexing_GetIndice (q->rangeArray, j));
     489         9858 :           if (r->low != SymbolTable_NulSym)
     490              :             {
     491              :               /* avoid gcc warning by using compound statement even if not strictly necessary.  */
     492         9858 :               if (SymbolTable_IsConst (r->low))
     493              :                 {
     494              :                   /* avoid dangling else.  */
     495         9858 :                   M2GCCDeclare_TryDeclareConstant (tokenno, r->low);
     496         9858 :                   if (! (SymbolConversion_GccKnowsAbout (r->low)))
     497              :                     {
     498              :                       return false;
     499              :                     }
     500              :                 }
     501              :               else
     502              :                 {
     503            0 :                   if (r->high == SymbolTable_NulSym)
     504              :                     {
     505            0 :                       M2MetaError_MetaError1 ((const char *) "the CASE statement variant must be defined by a constant {%1Da:is a {%1dv}}", 75, r->low);
     506              :                     }
     507              :                   else
     508              :                     {
     509            0 :                       M2MetaError_MetaError1 ((const char *) "the CASE statement variant low value in a range must be defined by a constant {%1Da:is a {%1dv}}", 96, r->low);
     510              :                     }
     511              :                 }
     512              :             }
     513         9774 :           if (r->high != SymbolTable_NulSym)
     514              :             {
     515              :               /* avoid gcc warning by using compound statement even if not strictly necessary.  */
     516          168 :               if (SymbolTable_IsConst (r->high))
     517              :                 {
     518              :                   /* avoid dangling else.  */
     519          168 :                   M2GCCDeclare_TryDeclareConstant (tokenno, r->high);
     520          168 :                   if (! (SymbolConversion_GccKnowsAbout (r->high)))
     521              :                     {
     522              :                       return false;
     523              :                     }
     524              :                 }
     525              :               else
     526              :                 {
     527            0 :                   M2MetaError_MetaError1 ((const char *) "the CASE statement variant high value in a range must be defined by a constant {%1Da:is a {%1dv}}", 97, r->high);
     528              :                 }
     529              :             }
     530         9774 :           j += 1;
     531              :         }
     532         9682 :       i += 1;
     533              :     }
     534              :   return true;
     535              :   /* static analysis guarentees a RETURN statement will be used before here.  */
     536              :   __builtin_unreachable ();
     537              : }
     538              : 
     539              : 
     540              : /*
     541              :    ConvertNulStr2NulChar -
     542              : */
     543              : 
     544         3964 : static void ConvertNulStr2NulChar (unsigned int tokenno, unsigned int c)
     545              : {
     546         3964 :   M2CaseList_CaseDescriptor p;
     547         3964 :   M2CaseList_CaseList q;
     548         3964 :   M2CaseList_RangePair r;
     549         3964 :   unsigned int i;
     550         3964 :   unsigned int j;
     551              : 
     552         3964 :   p = static_cast<M2CaseList_CaseDescriptor> (Indexing_GetIndice (caseArray, c));
     553         3964 :   i = 1;
     554        17594 :   while (i <= p->maxCaseId)
     555              :     {
     556         9666 :       q = static_cast<M2CaseList_CaseList> (Indexing_GetIndice (p->caseListArray, i));
     557         9666 :       j = 1;
     558        29090 :       while (j <= q->maxRangeId)
     559              :         {
     560         9758 :           r = static_cast<M2CaseList_RangePair> (Indexing_GetIndice (q->rangeArray, j));
     561         9758 :           r->low = NulStr2NulChar (tokenno, r->low);
     562         9758 :           r->high = NulStr2NulChar (tokenno, r->high);
     563         9758 :           j += 1;
     564              :         }
     565         9666 :       i += 1;
     566              :     }
     567         3964 : }
     568              : 
     569              : 
     570              : /*
     571              :    NulStr2NulChar - if sym is a const string of length 0 then return
     572              :                     a nul char instead otherwise return sym.
     573              : */
     574              : 
     575        19516 : static unsigned int NulStr2NulChar (unsigned int tok, unsigned int sym)
     576              : {
     577        19516 :   if (sym != SymbolTable_NulSym)
     578              :     {
     579         9926 :       if (((SymbolTable_IsConst (sym)) && (SymbolTable_IsConstString (sym))) && (SymbolConversion_GccKnowsAbout (sym)))
     580              :         {
     581          892 :           if ((SymbolTable_GetStringLength (tok, sym)) == 0)
     582              :             {
     583            6 :               sym = SymbolTable_MakeConstVar (tok, NameKey_NulName);
     584            6 :               SymbolTable_PutConst (sym, M2Base_Char);
     585            6 :               M2ALU_PushCard (0);
     586            6 :               SymbolTable_PopValue (sym);
     587            6 :               M2GCCDeclare_TryDeclareConstant (tok, sym);
     588            6 :               M2Debug_Assert (SymbolConversion_GccKnowsAbout (sym));
     589              :             }
     590              :         }
     591              :     }
     592        19516 :   return sym;
     593              :   /* static analysis guarentees a RETURN statement will be used before here.  */
     594              :   __builtin_unreachable ();
     595              : }
     596              : 
     597              : 
     598              : /*
     599              :    IsSame - return TRUE if r, s, are in, e.
     600              : */
     601              : 
     602           24 : static bool IsSame (M2CaseList_ConflictingPair e, M2CaseList_RangePair r, M2CaseList_RangePair s)
     603              : {
     604           24 :   return ((e->a == r) && (e->b == s)) || ((e->a == s) && (e->b == r));
     605              :   /* static analysis guarentees a RETURN statement will be used before here.  */
     606              :   __builtin_unreachable ();
     607              : }
     608              : 
     609              : 
     610              : /*
     611              :    SeenBefore -
     612              : */
     613              : 
     614           48 : static bool SeenBefore (M2CaseList_RangePair r, M2CaseList_RangePair s)
     615              : {
     616           48 :   unsigned int i;
     617           48 :   unsigned int h;
     618           48 :   M2CaseList_ConflictingPair e;
     619              : 
     620           48 :   h = Indexing_HighIndice (conflictArray);
     621           48 :   i = 1;
     622           96 :   while (i <= h)
     623              :     {
     624           24 :       e = static_cast<M2CaseList_ConflictingPair> (Indexing_GetIndice (conflictArray, i));
     625           24 :       if (IsSame (e, r, s))
     626              :         {
     627              :           return true;
     628              :         }
     629            0 :       i += 1;
     630              :     }
     631           24 :   Storage_ALLOCATE ((void **) &e, sizeof (M2CaseList__T2));
     632           24 :   e->a = r;
     633           24 :   e->b = s;
     634           24 :   Indexing_PutIndice (conflictArray, h+1, reinterpret_cast <void *> (e));
     635           24 :   return false;
     636              :   /* static analysis guarentees a RETURN statement will be used before here.  */
     637              :   __builtin_unreachable ();
     638              : }
     639              : 
     640              : 
     641              : /*
     642              :    Overlaps -
     643              : */
     644              : 
     645        60016 : static bool Overlaps (M2CaseList_RangePair r, M2CaseList_RangePair s)
     646              : {
     647        60016 :   unsigned int a;
     648        60016 :   unsigned int b;
     649        60016 :   unsigned int c;
     650        60016 :   unsigned int d;
     651              : 
     652        60016 :   a = r->low;
     653        60016 :   c = s->low;
     654        60016 :   if (r->high == SymbolTable_NulSym)
     655              :     {
     656              :       /* avoid dangling else.  */
     657        59512 :       b = a;
     658        59512 :       if (s->high == SymbolTable_NulSym)
     659              :         {
     660              :           /* avoid dangling else.  */
     661        59176 :           d = c;
     662        59176 :           if (M2Range_OverlapsRange (SymbolConversion_Mod2Gcc (a), SymbolConversion_Mod2Gcc (b), SymbolConversion_Mod2Gcc (c), SymbolConversion_Mod2Gcc (d)))
     663              :             {
     664           24 :               if (! (SeenBefore (r, s)))
     665              :                 {
     666           12 :                   M2MetaError_MetaErrorT2 (r->tokenno, (const char *) "case label {%1ad} is a duplicate with {%2ad}", 44, a, c);
     667           12 :                   M2MetaError_MetaErrorT2 (s->tokenno, (const char *) "case label {%1ad} is a duplicate with {%2ad}", 44, c, a);
     668              :                 }
     669           24 :               return true;
     670              :             }
     671              :         }
     672              :       else
     673              :         {
     674          336 :           d = s->high;
     675          336 :           if (M2Range_OverlapsRange (SymbolConversion_Mod2Gcc (a), SymbolConversion_Mod2Gcc (b), SymbolConversion_Mod2Gcc (c), SymbolConversion_Mod2Gcc (d)))
     676              :             {
     677            6 :               if (! (SeenBefore (r, s)))
     678              :                 {
     679            6 :                   M2MetaError_MetaErrorT3 (r->tokenno, (const char *) "case label {%1ad} is a duplicate in the range {%2ad}..{%3ad}", 60, a, c, d);
     680            6 :                   M2MetaError_MetaErrorT3 (s->tokenno, (const char *) "case range {%2ad}..{%3ad} is a duplicate of case label {%1ad}", 61, c, d, a);
     681              :                 }
     682            6 :               return true;
     683              :             }
     684              :         }
     685              :     }
     686              :   else
     687              :     {
     688          504 :       b = r->high;
     689          504 :       if (s->high == SymbolTable_NulSym)
     690              :         {
     691              :           /* avoid dangling else.  */
     692          336 :           d = c;
     693          336 :           if (M2Range_OverlapsRange (SymbolConversion_Mod2Gcc (a), SymbolConversion_Mod2Gcc (b), SymbolConversion_Mod2Gcc (c), SymbolConversion_Mod2Gcc (d)))
     694              :             {
     695            6 :               if (! (SeenBefore (r, s)))
     696              :                 {
     697            0 :                   M2MetaError_MetaErrorT3 (r->tokenno, (const char *) "case range {%1ad}..{%2ad} is a duplicate with case label {%3ad}", 63, a, b, c);
     698            0 :                   M2MetaError_MetaErrorT3 (s->tokenno, (const char *) "case label {%1ad} is a duplicate with case range %{2ad}..{%3ad}", 63, c, a, b);
     699              :                 }
     700            6 :               return true;
     701              :             }
     702              :         }
     703              :       else
     704              :         {
     705          168 :           d = s->high;
     706          168 :           if (M2Range_OverlapsRange (SymbolConversion_Mod2Gcc (a), SymbolConversion_Mod2Gcc (b), SymbolConversion_Mod2Gcc (c), SymbolConversion_Mod2Gcc (d)))
     707              :             {
     708           12 :               if (! (SeenBefore (r, s)))
     709              :                 {
     710            6 :                   M2MetaError_MetaErrorT4 (r->tokenno, (const char *) "case range {%1ad}..{%2ad} overlaps case range {%3ad}..{%4ad}", 60, a, b, c, d);
     711            6 :                   M2MetaError_MetaErrorT4 (s->tokenno, (const char *) "case range {%1ad}..{%2ad} overlaps case range {%3ad}..{%4ad}", 60, c, d, a, b);
     712              :                 }
     713           12 :               return true;
     714              :             }
     715              :         }
     716              :     }
     717              :   return false;
     718              :   /* static analysis guarentees a RETURN statement will be used before here.  */
     719              :   __builtin_unreachable ();
     720              : }
     721              : 
     722              : 
     723              : /*
     724              :    GetCaseExpression - return the type from the expression.
     725              : */
     726              : 
     727          156 : static unsigned int GetCaseExpression (M2CaseList_CaseDescriptor p)
     728              : {
     729          156 :   unsigned int type;
     730              : 
     731          156 :   if (p->expression == SymbolTable_NulSym)
     732              :     {
     733              :       type = SymbolTable_NulSym;
     734              :     }
     735              :   else
     736              :     {
     737          152 :       type = SymbolTable_SkipType (SymbolTable_GetType (p->expression));
     738              :     }
     739          156 :   return type;
     740              :   /* static analysis guarentees a RETURN statement will be used before here.  */
     741              :   __builtin_unreachable ();
     742              : }
     743              : 
     744              : 
     745              : /*
     746              :    OverlappingCaseBound - returns TRUE if, r, overlaps any case bound in the
     747              :                           case statement, c.
     748              : */
     749              : 
     750         9758 : static bool OverlappingCaseBound (M2CaseList_RangePair r, unsigned int c)
     751              : {
     752         9758 :   M2CaseList_CaseDescriptor p;
     753         9758 :   M2CaseList_CaseList q;
     754         9758 :   M2CaseList_RangePair s;
     755         9758 :   unsigned int i;
     756         9758 :   unsigned int j;
     757         9758 :   bool overlap;
     758              : 
     759         9758 :   p = static_cast<M2CaseList_CaseDescriptor> (Indexing_GetIndice (caseArray, c));
     760         9758 :   overlap = false;
     761         9758 :   i = 1;
     762        88958 :   while (i <= p->maxCaseId)
     763              :     {
     764        69442 :       q = static_cast<M2CaseList_CaseList> (Indexing_GetIndice (p->caseListArray, i));
     765        69442 :       j = 1;
     766       208658 :       while (j <= q->maxRangeId)
     767              :         {
     768        69774 :           s = static_cast<M2CaseList_RangePair> (Indexing_GetIndice (q->rangeArray, j));
     769        69774 :           if ((s != r) && (Overlaps (r, s)))
     770              :             {
     771              :               overlap = true;
     772              :             }
     773        69774 :           j += 1;
     774              :         }
     775        69442 :       i += 1;
     776              :     }
     777         9758 :   return overlap;
     778              :   /* static analysis guarentees a RETURN statement will be used before here.  */
     779              :   __builtin_unreachable ();
     780              : }
     781              : 
     782              : 
     783              : /*
     784              :    NewRanges - return a new range from the freelist or heap.
     785              : */
     786              : 
     787         1318 : static M2CaseList_SetRange NewRanges (void)
     788              : {
     789         1318 :   M2CaseList_SetRange s;
     790              : 
     791         1318 :   if (FreeRangeList == NULL)
     792              :     {
     793         1290 :       Storage_ALLOCATE ((void **) &s, sizeof (M2CaseList__T5));
     794              :     }
     795              :   else
     796              :     {
     797           28 :       s = FreeRangeList;
     798           28 :       FreeRangeList = FreeRangeList->next;
     799              :     }
     800         1318 :   s->next = NULL;
     801         1318 :   return s;
     802              :   /* static analysis guarentees a RETURN statement will be used before here.  */
     803              :   __builtin_unreachable ();
     804              : }
     805              : 
     806              : 
     807              : /*
     808              :    NewSet - returns a new set based on type with the low and high fields assigned
     809              :             to the min and max values for the type.
     810              : */
     811              : 
     812         1282 : static M2CaseList_SetRange NewSet (unsigned int type)
     813              : {
     814         1282 :   M2CaseList_SetRange s;
     815              : 
     816         1282 :   s = NewRanges ();
     817         1282 :   s->low = SymbolConversion_Mod2Gcc (M2GCCDeclare_GetTypeMin (type));
     818         1282 :   s->high = SymbolConversion_Mod2Gcc (M2GCCDeclare_GetTypeMax (type));
     819         1282 :   s->next = NULL;
     820         1282 :   return s;
     821              :   /* static analysis guarentees a RETURN statement will be used before here.  */
     822              :   __builtin_unreachable ();
     823              : }
     824              : 
     825              : 
     826              : /*
     827              :    DisposeRanges - place set and its list onto the free list.
     828              : */
     829              : 
     830         2510 : static M2CaseList_SetRange DisposeRanges (M2CaseList_SetRange set)
     831              : {
     832         2510 :   M2CaseList_SetRange t;
     833              : 
     834         2510 :   if (set != NULL)
     835              :     {
     836              :       /* avoid gcc warning by using compound statement even if not strictly necessary.  */
     837         1288 :       if (FreeRangeList == NULL)
     838              :         {
     839         1282 :           FreeRangeList = set;
     840              :         }
     841              :       else
     842              :         {
     843              :           t = set;
     844            6 :           while (t->next != NULL)
     845              :             {
     846              :               t = t->next;
     847              :             }
     848            6 :           t->next = FreeRangeList;
     849            6 :           FreeRangeList = set;
     850              :         }
     851              :     }
     852         2510 :   return NULL;
     853              :   /* static analysis guarentees a RETURN statement will be used before here.  */
     854              :   __builtin_unreachable ();
     855              : }
     856              : 
     857              : 
     858              : /*
     859              :    RemoveRange - removes the range descriptor h from set and return the
     860              :                  possibly new head of set.
     861              : */
     862              : 
     863         1228 : static M2CaseList_SetRange RemoveRange (M2CaseList_SetRange set, M2CaseList_SetRange h)
     864              : {
     865         1228 :   M2CaseList_SetRange i;
     866              : 
     867         1228 :   if (h == set)
     868              :     {
     869         1222 :       set = set->next;
     870         1222 :       h->next = NULL;
     871         1222 :       h = DisposeRanges (h);
     872              :     }
     873              :   else
     874              :     {
     875              :       i = set;
     876            6 :       while (i->next != h)
     877              :         {
     878              :           i = i->next;
     879              :         }
     880            6 :       i->next = h->next;
     881            6 :       i = h;
     882            6 :       h = h->next;
     883            6 :       i->next = NULL;
     884            6 :       i = DisposeRanges (i);
     885              :     }
     886         1228 :   return set;
     887              :   /* static analysis guarentees a RETURN statement will be used before here.  */
     888              :   __builtin_unreachable ();
     889              : }
     890              : 
     891              : 
     892              : /*
     893              :    SubBitRange - subtracts bits, lo..hi, from, set.
     894              : */
     895              : 
     896         2692 : static M2CaseList_SetRange SubBitRange (M2CaseList_SetRange set, tree lo, tree hi, unsigned int tokenno)
     897              : {
     898         2692 :   M2CaseList_SetRange h;
     899         2692 :   M2CaseList_SetRange i;
     900              : 
     901         2692 :   h = set;
     902              :   /* Check to see if a single set element h is obliterated by lo..hi.  */
     903         6884 :   while (h != NULL)
     904              :     {
     905         4204 :       if ((h->high == NULL) || (M2Range_IsEqual (h->high, h->low)))
     906              :         {
     907         2474 :           if ((M2Range_IsEqual (h->low, lo)) || (M2Range_OverlapsRange (lo, hi, h->low, h->low)))
     908              :             {
     909         1216 :               set = RemoveRange (set, h);
     910         1216 :               h = set;
     911              :             }
     912              :           else
     913              :             {
     914         1258 :               h = h->next;
     915              :             }
     916              :           /* Now check to see if the lo..hi match exactly with the set range.  */
     917              :         }
     918         1730 :       else if (((h->high != NULL) && (M2Range_IsEqual (lo, h->low))) && (M2Range_IsEqual (hi, h->high)))
     919              :         {
     920              :           /* avoid dangling else.  */
     921              :           /* Remove h and return as lo..hi have been removed.  */
     922           12 :           return RemoveRange (set, h);
     923              :         }
     924              :       else
     925              :         {
     926              :           /* avoid dangling else.  */
     927              :           /* All other cases require modifying the existing set range.  */
     928         1718 :           if (M2Range_OverlapsRange (lo, hi, h->low, h->high))
     929              :             {
     930         1458 :               if ((M2Range_IsGreater (h->low, lo)) || (M2Range_IsGreater (hi, h->high)))
     931              :                 {
     932            0 :                   M2MetaError_MetaErrorT0 (tokenno, (const char *) "variant case range lies outside tag value", 41);
     933              :                 }
     934              :               else
     935              :                 {
     936         1458 :                   if (M2Range_IsEqual (h->low, lo))
     937              :                     {
     938         1364 :                       M2ALU_PushIntegerTree (hi);
     939         1364 :                       M2ALU_PushInt (1);
     940         1364 :                       M2ALU_Addn ();
     941         1364 :                       h->low = M2ALU_PopIntegerTree ();
     942              :                     }
     943           94 :                   else if (M2Range_IsEqual (h->high, hi))
     944              :                     {
     945              :                       /* avoid dangling else.  */
     946           58 :                       M2ALU_PushIntegerTree (lo);
     947           58 :                       M2ALU_PushInt (1);
     948           58 :                       M2ALU_Sub ();
     949           58 :                       h->high = M2ALU_PopIntegerTree ();
     950              :                     }
     951              :                   else
     952              :                     {
     953              :                       /* avoid dangling else.  */
     954              :                       /* lo..hi  exist inside range h^.low..h^.high  */
     955           36 :                       i = NewRanges ();
     956           36 :                       i->next = h->next;
     957           36 :                       h->next = i;
     958           36 :                       i->high = h->high;
     959           36 :                       M2ALU_PushIntegerTree (lo);
     960           36 :                       M2ALU_PushInt (1);
     961           36 :                       M2ALU_Sub ();
     962           36 :                       h->high = M2ALU_PopIntegerTree ();
     963           36 :                       M2ALU_PushIntegerTree (hi);
     964           36 :                       M2ALU_PushInt (1);
     965           36 :                       M2ALU_Addn ();
     966           36 :                       i->low = M2ALU_PopIntegerTree ();
     967              :                     }
     968              :                 }
     969              :             }
     970              :           else
     971              :             {
     972          260 :               h = h->next;
     973              :             }
     974              :         }
     975              :     }
     976              :   return set;
     977              :   /* static analysis guarentees a RETURN statement will be used before here.  */
     978              :   __builtin_unreachable ();
     979              : }
     980              : 
     981              : 
     982              : /*
     983              :    CheckLowHigh - checks to see the low value <= high value and issues an error
     984              :                   if this is not true.
     985              : */
     986              : 
     987           66 : static void CheckLowHigh (M2CaseList_RangePair rp)
     988              : {
     989           66 :   tree lo;
     990           66 :   tree hi;
     991           66 :   unsigned int temp;
     992              : 
     993           66 :   lo = SymbolConversion_Mod2Gcc (rp->low);
     994           66 :   hi = SymbolConversion_Mod2Gcc (rp->high);
     995           66 :   if (M2Range_IsGreater (lo, hi))
     996              :     {
     997            0 :       M2MetaError_MetaErrorT2 (rp->tokenno, (const char *) "case range should be low..high rather than high..low, range specified as {%1Euad}..{%2Euad}", 91, rp->low, rp->high);
     998            0 :       temp = rp->high;
     999            0 :       rp->high = rp->low;
    1000            0 :       rp->low = temp;
    1001              :     }
    1002           66 : }
    1003              : 
    1004              : 
    1005              : /*
    1006              :    ExcludeCaseRanges - excludes all case ranges found in, p, from, set
    1007              : */
    1008              : 
    1009         1282 : static M2CaseList_SetRange ExcludeCaseRanges (M2CaseList_SetRange set, M2CaseList_CaseDescriptor cd)
    1010              : {
    1011         1282 :   unsigned int i;
    1012         1282 :   unsigned int j;
    1013         1282 :   M2CaseList_CaseList cl;
    1014         1282 :   M2CaseList_RangePair rp;
    1015              : 
    1016         1282 :   i = 1;
    1017         3924 :   while (i <= cd->maxCaseId)
    1018              :     {
    1019         2642 :       cl = static_cast<M2CaseList_CaseList> (Indexing_GetIndice (cd->caseListArray, i));
    1020         2642 :       j = 1;
    1021         7976 :       while (j <= cl->maxRangeId)
    1022              :         {
    1023         2692 :           rp = static_cast<M2CaseList_RangePair> (Indexing_GetIndice (cl->rangeArray, j));
    1024         2692 :           if (rp->high == SymbolTable_NulSym)
    1025              :             {
    1026         2626 :               set = SubBitRange (set, SymbolConversion_Mod2Gcc (rp->low), SymbolConversion_Mod2Gcc (rp->low), rp->tokenno);
    1027              :             }
    1028              :           else
    1029              :             {
    1030           66 :               CheckLowHigh (rp);
    1031           66 :               set = SubBitRange (set, SymbolConversion_Mod2Gcc (rp->low), SymbolConversion_Mod2Gcc (rp->high), rp->tokenno);
    1032              :             }
    1033         2692 :           j += 1;
    1034              :         }
    1035         2642 :       i += 1;
    1036              :     }
    1037         1282 :   return set;
    1038              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    1039              :   __builtin_unreachable ();
    1040              : }
    1041              : 
    1042              : 
    1043              : /*
    1044              :    IncludeElement - only include enumeration field into errorString if it lies between low..high.
    1045              : */
    1046              : 
    1047           18 : static void IncludeElement (Lists_List enumList, unsigned int field, tree low, tree high)
    1048              : {
    1049           18 :   tree fieldTree;
    1050              : 
    1051           18 :   if (field != SymbolTable_NulSym)
    1052              :     {
    1053           18 :       fieldTree = SymbolConversion_Mod2Gcc (field);
    1054           18 :       if (M2Range_OverlapsRange (fieldTree, fieldTree, low, high))
    1055              :         {
    1056            6 :           Lists_IncludeItemIntoList (enumList, field);
    1057              :         }
    1058              :     }
    1059           18 : }
    1060              : 
    1061              : 
    1062              : /*
    1063              :    IncludeElements - only include enumeration field values low..high in errorString.
    1064              : */
    1065              : 
    1066            6 : static void IncludeElements (unsigned int type, Lists_List enumList, tree low, tree high)
    1067              : {
    1068            6 :   unsigned int field;
    1069            6 :   unsigned int i;
    1070            6 :   unsigned int NoElements;
    1071              : 
    1072            6 :   NoElements = SymbolTable_NoOfElements (type);
    1073            6 :   i = 1;
    1074           30 :   while (i <= NoElements)
    1075              :     {
    1076           18 :       field = SymbolTable_GetNth (type, i);
    1077           18 :       IncludeElement (enumList, field, low, high);
    1078           18 :       i += 1;
    1079              :     }
    1080            6 : }
    1081              : 
    1082              : 
    1083              : /*
    1084              :    ErrorRangeEnum - include enumeration fields Low to High in errorString.
    1085              : */
    1086              : 
    1087            6 : static void ErrorRangeEnum (unsigned int type, M2CaseList_SetRange set, Lists_List enumList)
    1088              : {
    1089            6 :   tree Low;
    1090            6 :   tree High;
    1091              : 
    1092            6 :   Low = set->low;
    1093            6 :   High = set->high;
    1094            6 :   if (Low == NULL)
    1095              :     {
    1096            0 :       Low = High;
    1097              :     }
    1098            6 :   if (High == NULL)
    1099              :     {
    1100            0 :       High = Low;
    1101              :     }
    1102            6 :   if ((Low != NULL) && (High != NULL))
    1103              :     {
    1104            6 :       IncludeElements (type, enumList, Low, High);
    1105              :     }
    1106            6 : }
    1107              : 
    1108              : 
    1109              : /*
    1110              :    ErrorRanges - return a list of all enumeration fields not present in the case statement.
    1111              :                  The return value will be nil if type is not an enumeration type.
    1112              : */
    1113              : 
    1114            6 : static Lists_List ErrorRanges (unsigned int type, M2CaseList_SetRange set)
    1115              : {
    1116            6 :   Lists_List enumSet;
    1117              : 
    1118            6 :   type = SymbolTable_SkipType (type);
    1119            6 :   if (SymbolTable_IsEnumeration (type))
    1120              :     {
    1121            6 :       Lists_InitList (&enumSet);
    1122           18 :       while (set != NULL)
    1123              :         {
    1124            6 :           ErrorRangeEnum (type, set, enumSet);
    1125            6 :           set = set->next;
    1126              :         }
    1127            6 :       return enumSet;
    1128              :     }
    1129              :   return static_cast<Lists_List> (NULL);
    1130              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    1131              :   __builtin_unreachable ();
    1132              : }
    1133              : 
    1134              : 
    1135              : /*
    1136              :    appendString - appends str to errorString.
    1137              : */
    1138              : 
    1139          450 : static void appendString (DynamicStrings_String str)
    1140              : {
    1141          450 :   errorString = DynamicStrings_ConCat (errorString, str);
    1142          450 : }
    1143              : 
    1144              : 
    1145              : /*
    1146              :    appendEnum - appends enum to errorString.
    1147              : */
    1148              : 
    1149            6 : static void appendEnum (unsigned int enum_)
    1150              : {
    1151            6 :   appendString (DynamicStrings_Mark (DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetSymName (enum_)))));
    1152            6 : }
    1153              : 
    1154              : 
    1155              : /*
    1156              :    appendStr - appends str to errorString.
    1157              : */
    1158              : 
    1159          162 : static void appendStr (const char *str_, unsigned int _str_high)
    1160              : {
    1161          162 :   char str[_str_high+1];
    1162              : 
    1163              :   /* make a local copy of each unbounded array.  */
    1164          162 :   memcpy (str, str_, _str_high+1);
    1165              : 
    1166          162 :   appendString (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) str, _str_high)));
    1167          162 : }
    1168              : 
    1169              : 
    1170              : /*
    1171              :    EnumerateErrors - populate errorString with the contents of enumList.
    1172              : */
    1173              : 
    1174            6 : static void EnumerateErrors (Lists_List enumList)
    1175              : {
    1176            6 :   unsigned int i;
    1177            6 :   unsigned int n;
    1178              : 
    1179            6 :   n = Lists_NoOfItemsInList (enumList);
    1180            6 :   if ((enumList != NULL) && (n > 0))
    1181              :     {
    1182            6 :       if (n == 1)
    1183              :         {
    1184            6 :           errorString = DynamicStrings_InitString ((const char *) "{%W}the missing enumeration field is: ", 38);
    1185              :         }
    1186              :       else
    1187              :         {
    1188            0 :           errorString = DynamicStrings_InitString ((const char *) "{%W}the missing enumeration fields are: ", 40);
    1189              :         }
    1190            6 :       appendEnum (Lists_GetItemFromList (enumList, 1));
    1191            6 :       if (n > 1)
    1192              :         {
    1193            0 :           if (n > 2)
    1194              :             {
    1195              :               i = 2;
    1196            0 :               while (i <= (n-1))
    1197              :                 {
    1198            0 :                   appendStr ((const char *) ", ", 2);
    1199            0 :                   appendEnum (Lists_GetItemFromList (enumList, i));
    1200            0 :                   i += 1;
    1201              :                 }
    1202              :             }
    1203            0 :           appendStr ((const char *) " and ", 5);
    1204            0 :           appendEnum (Lists_GetItemFromList (enumList, n));
    1205              :         }
    1206              :     }
    1207            6 : }
    1208              : 
    1209              : 
    1210              : /*
    1211              :    NoOfSetElements - return the number of set elements.
    1212              : */
    1213              : 
    1214           42 : static tree NoOfSetElements (M2CaseList_SetRange set)
    1215              : {
    1216           42 :   M2ALU_PushInt (0);
    1217          156 :   while (set != NULL)
    1218              :     {
    1219           72 :       if (((set->low != NULL) && (set->high == NULL)) || ((set->low == NULL) && (set->high != NULL)))
    1220              :         {
    1221            0 :           M2ALU_PushInt (1);
    1222            0 :           M2ALU_Addn ();
    1223              :         }
    1224           72 :       else if ((set->low != NULL) && (set->high != NULL))
    1225              :         {
    1226              :           /* avoid dangling else.  */
    1227           72 :           M2ALU_PushIntegerTree (set->high);
    1228           72 :           M2ALU_PushIntegerTree (set->low);
    1229           72 :           M2ALU_Sub ();
    1230           72 :           M2ALU_PushInt (1);
    1231           72 :           M2ALU_Addn ();
    1232           72 :           M2ALU_Addn ();
    1233              :         }
    1234           72 :       set = set->next;
    1235              :     }
    1236           42 :   return M2ALU_PopIntegerTree ();
    1237              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    1238              :   __builtin_unreachable ();
    1239              : }
    1240              : 
    1241              : 
    1242              : /*
    1243              :    isPrintableChar - a cautious isprint.
    1244              : */
    1245              : 
    1246           60 : static bool isPrintableChar (tree value)
    1247              : {
    1248           60 :   if (((m2expr_CSTIntToChar (value)) >= 'a') && ((m2expr_CSTIntToChar (value)) <= 'z'))
    1249              :   {
    1250              :   return true;
    1251              :   }
    1252           18 :   else if (((m2expr_CSTIntToChar (value)) >= 'A') && ((m2expr_CSTIntToChar (value)) <= 'Z'))
    1253              :   {
    1254              :   return true;
    1255              :   }
    1256           18 :   else if (((m2expr_CSTIntToChar (value)) >= '0') && ((m2expr_CSTIntToChar (value)) <= '9'))
    1257              :   {
    1258              :   return true;
    1259              :   }
    1260           18 :   else if (((m2expr_CSTIntToChar (value)) == '!') || ((m2expr_CSTIntToChar (value)) == '@'))
    1261              :   {
    1262            0 :   return true;
    1263              :   }
    1264           18 :   else if (((m2expr_CSTIntToChar (value)) == '#') || ((m2expr_CSTIntToChar (value)) == '$'))
    1265              :   {
    1266            0 :   return true;
    1267              :   }
    1268           18 :   else if (((m2expr_CSTIntToChar (value)) == '%') || ((m2expr_CSTIntToChar (value)) == '^'))
    1269              :   {
    1270            0 :   return true;
    1271              :   }
    1272           18 :   else if (((m2expr_CSTIntToChar (value)) == '&') || ((m2expr_CSTIntToChar (value)) == '*'))
    1273              :   {
    1274            0 :   return true;
    1275              :   }
    1276           18 :   else if (((m2expr_CSTIntToChar (value)) == '(') || ((m2expr_CSTIntToChar (value)) == ')'))
    1277              :   {
    1278            0 :   return true;
    1279              :   }
    1280           18 :   else if (((m2expr_CSTIntToChar (value)) == '[') || ((m2expr_CSTIntToChar (value)) == ']'))
    1281              :   {
    1282            0 :   return true;
    1283              :   }
    1284           18 :   else if (((m2expr_CSTIntToChar (value)) == '{') || ((m2expr_CSTIntToChar (value)) == '}'))
    1285              :   {
    1286            0 :   return true;
    1287              :   }
    1288           18 :   else if (((m2expr_CSTIntToChar (value)) == '-') || ((m2expr_CSTIntToChar (value)) == '+'))
    1289              :   {
    1290            0 :   return true;
    1291              :   }
    1292           18 :   else if (((m2expr_CSTIntToChar (value)) == '_') || ((m2expr_CSTIntToChar (value)) == '='))
    1293              :   {
    1294            0 :   return true;
    1295              :   }
    1296           18 :   else if (((m2expr_CSTIntToChar (value)) == ':') || ((m2expr_CSTIntToChar (value)) == ';'))
    1297              :   {
    1298            0 :   return true;
    1299              :   }
    1300           18 :   else if (((m2expr_CSTIntToChar (value)) == '\'') || ((m2expr_CSTIntToChar (value)) == '"'))
    1301              :   {
    1302            0 :   return true;
    1303              :   }
    1304           18 :   else if (((m2expr_CSTIntToChar (value)) == ',') || ((m2expr_CSTIntToChar (value)) == '.'))
    1305              :   {
    1306            0 :   return true;
    1307              :   }
    1308           18 :   else if (((m2expr_CSTIntToChar (value)) == '<') || ((m2expr_CSTIntToChar (value)) == '>'))
    1309              :   {
    1310            0 :   return true;
    1311              :   }
    1312           18 :   else if (((m2expr_CSTIntToChar (value)) == '/') || ((m2expr_CSTIntToChar (value)) == '?'))
    1313              :   {
    1314            0 :   return true;
    1315              :   }
    1316           18 :   else if (((m2expr_CSTIntToChar (value)) == '\\') || ((m2expr_CSTIntToChar (value)) == '|'))
    1317              :   {
    1318            0 :   return true;
    1319              :   }
    1320           18 :   else if (((m2expr_CSTIntToChar (value)) == '~') || ((m2expr_CSTIntToChar (value)) == '`'))
    1321              :   {
    1322            6 :   return true;
    1323              :   }
    1324           12 :   else if (((m2expr_CSTIntToChar (value)) == ' '))
    1325              :   {
    1326              :   return true;
    1327              :   }
    1328              : 
    1329              :   else {
    1330              :     return false;
    1331              :   }
    1332              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    1333              :   __builtin_unreachable ();
    1334              : }
    1335              : 
    1336              : 
    1337              : /*
    1338              :    appendTree - append tree value to the errorString.  It attempts to pretty print
    1339              :                 CHAR constants and will fall back to CHR (x) if necessary.
    1340              : */
    1341              : 
    1342          120 : static void appendTree (tree value, unsigned int type)
    1343              : {
    1344          120 :   if ((SymbolTable_SkipType (SymbolTable_GetType (type))) == M2Base_Char)
    1345              :     {
    1346           60 :       if (isPrintableChar (value))
    1347              :         {
    1348           48 :           if ((m2expr_CSTIntToChar (value)) == '\'')
    1349              :             {
    1350            0 :               appendString (DynamicStrings_InitStringChar ('"'));
    1351            0 :               appendString (DynamicStrings_InitStringChar (m2expr_CSTIntToChar (value)));
    1352            0 :               appendString (DynamicStrings_InitStringChar ('"'));
    1353              :             }
    1354              :           else
    1355              :             {
    1356           48 :               appendString (DynamicStrings_InitStringChar ('\''));
    1357           48 :               appendString (DynamicStrings_InitStringChar (m2expr_CSTIntToChar (value)));
    1358           48 :               appendString (DynamicStrings_InitStringChar ('\''));
    1359              :             }
    1360              :         }
    1361              :       else
    1362              :         {
    1363           12 :           appendString (DynamicStrings_InitString ((const char *) "CHR (", 5));
    1364           12 :           appendString (DynamicStrings_InitStringCharStar (reinterpret_cast <void *> (m2expr_CSTIntToString (value))));
    1365           12 :           appendString (DynamicStrings_InitStringChar (')'));
    1366              :         }
    1367              :     }
    1368              :   else
    1369              :     {
    1370           60 :       appendString (DynamicStrings_InitStringCharStar (reinterpret_cast <void *> (m2expr_CSTIntToString (value))));
    1371              :     }
    1372          120 : }
    1373              : 
    1374              : 
    1375              : /*
    1376              :    SubrangeErrors - create an errorString containing all set ranges.
    1377              : */
    1378              : 
    1379           42 : static void SubrangeErrors (unsigned int subrangetype, M2CaseList_SetRange set)
    1380              : {
    1381           42 :   M2CaseList_SetRange sr;
    1382           42 :   unsigned int rangeNo;
    1383           42 :   tree nMissing;
    1384           42 :   tree zero;
    1385           42 :   tree one;
    1386              : 
    1387           42 :   nMissing = NoOfSetElements (set);
    1388           42 :   M2ALU_PushInt (0);
    1389           42 :   zero = M2ALU_PopIntegerTree ();
    1390           42 :   if (M2Range_IsGreater (nMissing, zero))
    1391              :     {
    1392           42 :       M2ALU_PushInt (1);
    1393           42 :       one = M2ALU_PopIntegerTree ();
    1394           42 :       if (M2Range_IsGreater (nMissing, one))
    1395              :         {
    1396           30 :           errorString = DynamicStrings_InitString ((const char *) "{%W}there are a total of ", 25);
    1397              :         }
    1398              :       else
    1399              :         {
    1400           12 :           errorString = DynamicStrings_InitString ((const char *) "{%W}there is a total of ", 24);
    1401              :         }
    1402           42 :       appendString (DynamicStrings_InitStringCharStar (reinterpret_cast <void *> (m2expr_CSTIntToString (nMissing))));
    1403           42 :       appendStr ((const char *) " missing values in the subrange, the {%kCASE} statement needs labels (or an {%kELSE} statement)", 95);
    1404           42 :       appendStr ((const char *) " for the following values: ", 27);
    1405           42 :       sr = set;
    1406           42 :       rangeNo = 0;
    1407          156 :       while (sr != NULL)
    1408              :         {
    1409           72 :           rangeNo += 1;
    1410           72 :           if (rangeNo > 1)
    1411              :             {
    1412              :               /* avoid gcc warning by using compound statement even if not strictly necessary.  */
    1413           30 :               if (sr->next == NULL)
    1414              :                 {
    1415           24 :                   appendStr ((const char *) " and ", 5);
    1416              :                 }
    1417              :               else
    1418              :                 {
    1419            6 :                   appendStr ((const char *) ", ", 2);
    1420              :                 }
    1421              :             }
    1422           72 :           if (sr->low == NULL)
    1423              :             {
    1424            0 :               appendTree (sr->high, subrangetype);
    1425              :             }
    1426           72 :           else if ((sr->high == NULL) || (M2Range_IsEqual (sr->low, sr->high)))
    1427              :             {
    1428              :               /* avoid dangling else.  */
    1429           24 :               appendTree (sr->low, subrangetype);
    1430              :             }
    1431              :           else
    1432              :             {
    1433              :               /* avoid dangling else.  */
    1434           48 :               appendTree (sr->low, subrangetype);
    1435           48 :               appendStr ((const char *) "..", 2);
    1436           48 :               appendTree (sr->high, subrangetype);
    1437              :             }
    1438           72 :           sr = sr->next;
    1439              :         }
    1440              :     }
    1441           42 : }
    1442              : 
    1443              : 
    1444              : /*
    1445              :    EmitMissingRangeErrors - emits a singular/plural error message for an enumeration type.
    1446              : */
    1447              : 
    1448           60 : static void EmitMissingRangeErrors (unsigned int tokenno, unsigned int type, M2CaseList_SetRange set)
    1449              : {
    1450           60 :   errorString = static_cast<DynamicStrings_String> (NULL);
    1451           60 :   if (SymbolTable_IsEnumeration (type))
    1452              :     {
    1453            6 :       EnumerateErrors (ErrorRanges (type, set));
    1454              :     }
    1455           54 :   else if (SymbolTable_IsSubrange (type))
    1456              :     {
    1457              :       /* avoid dangling else.  */
    1458           42 :       SubrangeErrors (type, set);
    1459              :     }
    1460           60 :   if (errorString != NULL)
    1461              :     {
    1462           48 :       M2MetaError_MetaErrorStringT0 (tokenno, errorString);
    1463              :     }
    1464           60 : }
    1465              : 
    1466              : 
    1467              : /*
    1468              :    checkTypes - checks to see that, constant, and, type, are compatible.
    1469              : */
    1470              : 
    1471        12036 : static bool checkTypes (unsigned int constant, unsigned int type)
    1472              : {
    1473        12036 :   unsigned int consttype;
    1474              : 
    1475        12036 :   if ((constant != SymbolTable_NulSym) && (SymbolTable_IsConst (constant)))
    1476              :     {
    1477         6018 :       consttype = SymbolTable_GetType (constant);
    1478         6018 :       if (! (M2Base_IsExpressionCompatible (consttype, type)))
    1479              :         {
    1480            0 :           M2MetaError_MetaError2 ((const char *) "the case statement variant tag {%1ad} must be type compatible with the constant {%2Da:is a {%2dv}}", 98, type, constant);
    1481            0 :           return false;
    1482              :         }
    1483              :     }
    1484              :   return true;
    1485              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    1486              :   __builtin_unreachable ();
    1487              : }
    1488              : 
    1489              : 
    1490              : /*
    1491              :    inRange - returns true if, min <= i <= max.
    1492              : */
    1493              : 
    1494         6018 : static bool inRange (unsigned int i, unsigned int min, unsigned int max)
    1495              : {
    1496         6018 :   return M2Range_OverlapsRange (SymbolConversion_Mod2Gcc (i), SymbolConversion_Mod2Gcc (i), SymbolConversion_Mod2Gcc (min), SymbolConversion_Mod2Gcc (max));
    1497              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    1498              :   __builtin_unreachable ();
    1499              : }
    1500              : 
    1501              : 
    1502              : /*
    1503              :    PushCase - create a case entity and push it to an internal stack.
    1504              :               rec is NulSym if this is a CASE statement.
    1505              :               If rec is a record then it indicates a possible
    1506              :               varients reside in the record to check.
    1507              :               Both rec and va might be NulSym and then the expr
    1508              :               will contain the selector expression to a case statement.
    1509              :               Return the case id.
    1510              : */
    1511              : 
    1512         3964 : extern "C" unsigned int M2CaseList_PushCase (unsigned int rec, unsigned int va, unsigned int expr)
    1513              : {
    1514         3964 :   M2CaseList_CaseDescriptor c;
    1515              : 
    1516         3964 :   caseId += 1;
    1517         3964 :   Storage_ALLOCATE ((void **) &c, sizeof (M2CaseList__T4));
    1518         3964 :   if (c == NULL)
    1519              :     {
    1520            0 :       M2Error_InternalError ((const char *) "out of memory error", 19);
    1521              :     }
    1522              :   else
    1523              :     {
    1524         3964 :       c->resolved = false;
    1525         3964 :       c->elseClause = false;
    1526         3964 :       c->elseField = SymbolTable_NulSym;
    1527         3964 :       c->record = rec;
    1528         3964 :       c->varient = va;
    1529         3964 :       c->expression = expr;
    1530         3964 :       c->maxCaseId = 0;
    1531         3964 :       c->caseListArray = Indexing_InitIndex (1);
    1532         3964 :       c->next = caseStack;
    1533         3964 :       c->currentCase = NULL;
    1534         3964 :       caseStack = c;
    1535         3964 :       Indexing_PutIndice (caseArray, caseId, reinterpret_cast <void *> (c));
    1536              :     }
    1537         3964 :   return caseId;
    1538              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    1539              :   __builtin_unreachable ();
    1540              : }
    1541              : 
    1542              : 
    1543              : /*
    1544              :    PopCase - pop the top element of the case entity from the internal
    1545              :              stack.
    1546              : */
    1547              : 
    1548         3964 : extern "C" void M2CaseList_PopCase (void)
    1549              : {
    1550         3964 :   if (caseStack == NULL)
    1551              :     {
    1552            0 :       M2Error_InternalError ((const char *) "case stack is empty", 19);
    1553              :     }
    1554         3964 :   caseStack = caseStack->next;
    1555         3964 : }
    1556              : 
    1557              : 
    1558              : /*
    1559              :    ElseCase - indicates that this case varient does have an else clause.
    1560              : */
    1561              : 
    1562          602 : extern "C" void M2CaseList_ElseCase (unsigned int f)
    1563              : {
    1564          602 :   caseStack->elseClause = true;
    1565          602 :   caseStack->elseField = f;
    1566          602 : }
    1567              : 
    1568              : 
    1569              : /*
    1570              :    BeginCaseList - create a new label list.
    1571              : */
    1572              : 
    1573         9666 : extern "C" void M2CaseList_BeginCaseList (unsigned int v)
    1574              : {
    1575         9666 :   M2CaseList_CaseList l;
    1576              : 
    1577         9666 :   Storage_ALLOCATE ((void **) &l, sizeof (M2CaseList__T3));
    1578         9666 :   if (l == NULL)
    1579              :     {
    1580            0 :       M2Error_InternalError ((const char *) "out of memory error", 19);
    1581              :     }
    1582         9666 :   l->maxRangeId = 0;
    1583         9666 :   l->rangeArray = Indexing_InitIndex (1);
    1584         9666 :   l->currentRange = NULL;
    1585         9666 :   l->varientField = v;
    1586         9666 :   caseStack->maxCaseId += 1;
    1587         9666 :   Indexing_PutIndice (caseStack->caseListArray, caseStack->maxCaseId, reinterpret_cast <void *> (l));
    1588         9666 :   caseStack->currentCase = l;
    1589         9666 : }
    1590              : 
    1591              : 
    1592              : /*
    1593              :    EndCaseList - terminate the current label list.
    1594              : */
    1595              : 
    1596         9666 : extern "C" void M2CaseList_EndCaseList (void)
    1597              : {
    1598         9666 :   caseStack->currentCase = NULL;
    1599         9666 : }
    1600              : 
    1601              : 
    1602              : /*
    1603              :    AddRange - add a range to the current label list.
    1604              : */
    1605              : 
    1606         9758 : extern "C" void M2CaseList_AddRange (unsigned int r1, unsigned int r2, unsigned int tok)
    1607              : {
    1608         9758 :   M2CaseList_RangePair r;
    1609              : 
    1610         9758 :   Storage_ALLOCATE ((void **) &r, sizeof (M2CaseList__T1));
    1611         9758 :   if (r == NULL)
    1612              :     {
    1613            0 :       M2Error_InternalError ((const char *) "out of memory error", 19);
    1614              :     }
    1615              :   else
    1616              :     {
    1617         9758 :       r->low = r1;
    1618         9758 :       r->high = r2;
    1619         9758 :       r->tokenno = tok;
    1620         9758 :       caseStack->currentCase->maxRangeId += 1;
    1621         9758 :       Indexing_PutIndice (caseStack->currentCase->rangeArray, caseStack->currentCase->maxRangeId, reinterpret_cast <void *> (r));
    1622         9758 :       caseStack->currentCase->currentRange = r;
    1623              :     }
    1624         9758 : }
    1625              : 
    1626              : 
    1627              : /*
    1628              :    CaseBoundsResolved - returns TRUE if all constants in the case list, c,
    1629              :                         are known to GCC.
    1630              : */
    1631              : 
    1632         9676 : extern "C" bool M2CaseList_CaseBoundsResolved (unsigned int tokenno, unsigned int c)
    1633              : {
    1634         9676 :   M2CaseList_CaseDescriptor p;
    1635              : 
    1636         9676 :   p = static_cast<M2CaseList_CaseDescriptor> (Indexing_GetIndice (caseArray, c));
    1637         9676 :   if (p->resolved)
    1638              :     {
    1639              :       return true;
    1640              :     }
    1641              :   else
    1642              :     {
    1643         9676 :       if (CheckCaseBoundsResolved (tokenno, c))
    1644              :         {
    1645         3964 :           ConvertNulStr2NulChar (tokenno, c);
    1646         3964 :           return true;
    1647              :         }
    1648              :       else
    1649              :         {
    1650              :           return false;
    1651              :         }
    1652              :     }
    1653              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    1654              :   __builtin_unreachable ();
    1655              : }
    1656              : 
    1657              : 
    1658              : /*
    1659              :    TypeCaseBounds - returns true if all bounds in case list, c, are
    1660              :                     compatible with the tagged type.
    1661              : */
    1662              : 
    1663         3964 : extern "C" bool M2CaseList_TypeCaseBounds (unsigned int c)
    1664              : {
    1665         3964 :   M2CaseList_CaseDescriptor p;
    1666         3964 :   M2CaseList_CaseList q;
    1667         3964 :   M2CaseList_RangePair r;
    1668         3964 :   unsigned int min;
    1669         3964 :   unsigned int max;
    1670         3964 :   unsigned int type;
    1671         3964 :   unsigned int i;
    1672         3964 :   unsigned int j;
    1673         3964 :   bool compatible;
    1674              : 
    1675         3964 :   p = static_cast<M2CaseList_CaseDescriptor> (Indexing_GetIndice (caseArray, c));
    1676         3964 :   type = SymbolTable_NulSym;
    1677         3964 :   type = SymbolTable_NulSym;
    1678         3964 :   if (p->varient != SymbolTable_NulSym)
    1679              :     {
    1680              :       /* not a CASE statement, but a varient record containing without an ELSE clause  */
    1681         2988 :       type = GetVariantTagType (p->varient);
    1682         2988 :       min = M2GCCDeclare_GetTypeMin (type);
    1683         2988 :       max = M2GCCDeclare_GetTypeMax (type);
    1684              :     }
    1685         2988 :   if (type == SymbolTable_NulSym)
    1686              :     {
    1687          976 :       return true;
    1688              :     }
    1689              :   compatible = true;
    1690              :   i = 1;
    1691         8964 :   while (i <= p->maxCaseId)
    1692              :     {
    1693         5976 :       q = static_cast<M2CaseList_CaseList> (Indexing_GetIndice (p->caseListArray, i));
    1694         5976 :       j = 1;
    1695        17970 :       while (j <= q->maxRangeId)
    1696              :         {
    1697         6018 :           r = static_cast<M2CaseList_RangePair> (Indexing_GetIndice (q->rangeArray, j));
    1698         6018 :           if ((r->low != SymbolTable_NulSym) && (! (inRange (r->low, min, max))))
    1699              :             {
    1700            0 :               M2MetaError_MetaError2 ((const char *) "the CASE statement variant range {%1ad} exceeds that of the tag type {%2ad}", 75, r->low, type);
    1701            0 :               compatible = false;
    1702              :             }
    1703         6018 :           if (! (checkTypes (r->low, type)))
    1704              :             {
    1705            0 :               compatible = false;
    1706              :             }
    1707         6018 :           if ((r->high != SymbolTable_NulSym) && (! (inRange (r->high, min, max))))
    1708              :             {
    1709            0 :               M2MetaError_MetaError2 ((const char *) "the CASE statement variant range {%1ad} exceeds that of the tag type {%2ad}", 75, r->high, type);
    1710            0 :               compatible = false;
    1711              :             }
    1712         6018 :           if (! (checkTypes (r->high, type)))
    1713              :             {
    1714            0 :               compatible = false;
    1715              :             }
    1716         6018 :           j += 1;
    1717              :         }
    1718         5976 :       i += 1;
    1719              :     }
    1720              :   return compatible;
    1721              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    1722              :   __builtin_unreachable ();
    1723              : }
    1724              : 
    1725              : 
    1726              : /*
    1727              :    OverlappingCaseBounds - returns TRUE if there were any overlapping bounds
    1728              :                            in the case list, c.  It will generate an error
    1729              :                            messages for each overlapping bound found.
    1730              : */
    1731              : 
    1732         3964 : extern "C" bool M2CaseList_OverlappingCaseBounds (unsigned int c)
    1733              : {
    1734         3964 :   M2CaseList_CaseDescriptor p;
    1735         3964 :   M2CaseList_CaseList q;
    1736         3964 :   M2CaseList_RangePair r;
    1737         3964 :   unsigned int i;
    1738         3964 :   unsigned int j;
    1739         3964 :   bool overlap;
    1740              : 
    1741         3964 :   p = static_cast<M2CaseList_CaseDescriptor> (Indexing_GetIndice (caseArray, c));
    1742         3964 :   overlap = false;
    1743         3964 :   i = 1;
    1744        17594 :   while (i <= p->maxCaseId)
    1745              :     {
    1746         9666 :       q = static_cast<M2CaseList_CaseList> (Indexing_GetIndice (p->caseListArray, i));
    1747         9666 :       j = 1;
    1748        29090 :       while (j <= q->maxRangeId)
    1749              :         {
    1750         9758 :           r = static_cast<M2CaseList_RangePair> (Indexing_GetIndice (q->rangeArray, j));
    1751         9758 :           if (OverlappingCaseBound (r, c))
    1752              :             {
    1753           48 :               overlap = true;
    1754              :             }
    1755         9758 :           j += 1;
    1756              :         }
    1757         9666 :       i += 1;
    1758              :     }
    1759         3964 :   return overlap;
    1760              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    1761              :   __builtin_unreachable ();
    1762              : }
    1763              : 
    1764              : 
    1765              : /*
    1766              :    MissingCaseBounds - returns true if there were any missing bounds
    1767              :                        in the varient record case list, c.  It will
    1768              :                        generate an error message for each missing
    1769              :                        bounds found.
    1770              : */
    1771              : 
    1772         1496 : extern "C" bool M2CaseList_MissingCaseBounds (unsigned int tokenno, unsigned int c)
    1773              : {
    1774         1496 :   M2CaseList_CaseDescriptor p;
    1775         1496 :   unsigned int type;
    1776         1496 :   bool missing;
    1777         1496 :   M2CaseList_SetRange set;
    1778              : 
    1779         1496 :   p = static_cast<M2CaseList_CaseDescriptor> (Indexing_GetIndice (caseArray, c));
    1780         1496 :   missing = false;
    1781         1496 :   if (! p->elseClause)
    1782              :     {
    1783         1394 :       if ((p->record != SymbolTable_NulSym) && (p->varient != SymbolTable_NulSym))
    1784              :         {
    1785              :           /* Not a case statement, but a varient record without an else clause.  */
    1786         1146 :           type = GetVariantTagType (p->varient);
    1787         1146 :           set = NewSet (type);
    1788         1146 :           set = ExcludeCaseRanges (set, p);
    1789         1146 :           if (set != NULL)
    1790              :             {
    1791           12 :               missing = true;
    1792           12 :               M2MetaError_MetaErrorT2 (tokenno, (const char *) "not all variant record alternatives in the {%kCASE} clause are specified, hint you either need to specify each value of {%2ad} or use an {%kELSE} clause", 152, p->varient, type);
    1793           12 :               EmitMissingRangeErrors (tokenno, type, set);
    1794              :             }
    1795         1146 :           set = DisposeRanges (set);
    1796              :         }
    1797              :     }
    1798         1496 :   return missing;
    1799              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    1800              :   __builtin_unreachable ();
    1801              : }
    1802              : 
    1803              : 
    1804              : /*
    1805              :    MissingCaseStatementBounds - returns true if the case statement has a missing
    1806              :                                 clause.  It will also generate error messages.
    1807              : */
    1808              : 
    1809          212 : extern "C" bool M2CaseList_MissingCaseStatementBounds (unsigned int tokenno, unsigned int c)
    1810              : {
    1811          212 :   M2CaseList_CaseDescriptor p;
    1812          212 :   unsigned int type;
    1813          212 :   bool missing;
    1814          212 :   M2CaseList_SetRange set;
    1815              : 
    1816          212 :   p = static_cast<M2CaseList_CaseDescriptor> (Indexing_GetIndice (caseArray, c));
    1817          212 :   missing = false;
    1818          212 :   if (! p->elseClause)
    1819              :     {
    1820          156 :       type = GetCaseExpression (p);
    1821          156 :       if (type != SymbolTable_NulSym)
    1822              :         {
    1823          152 :           if ((SymbolTable_IsEnumeration (type)) || (SymbolTable_IsSubrange (type)))
    1824              :             {
    1825              :               /* A case statement sequence without an else clause but
    1826              :                   selecting using an enumeration type.  */
    1827          136 :               set = NewSet (type);
    1828          136 :               set = ExcludeCaseRanges (set, p);
    1829          136 :               if (set != NULL)
    1830              :                 {
    1831           48 :                   missing = true;
    1832           48 :                   M2MetaError_MetaErrorT1 (tokenno, (const char *) "not all {%1Wd} values in the {%kCASE} statements are specified, hint you either need to specify each value of {%1ad} or use an {%kELSE} clause", 142, type);
    1833           48 :                   EmitMissingRangeErrors (tokenno, type, set);
    1834              :                 }
    1835          136 :               set = DisposeRanges (set);
    1836              :             }
    1837              :         }
    1838              :     }
    1839          212 :   return missing;
    1840              :   /* static analysis guarentees a RETURN statement will be used before here.  */
    1841              :   __builtin_unreachable ();
    1842              : }
    1843              : 
    1844              : 
    1845              : /*
    1846              :    WriteCase - dump out the case list (internal debugging).
    1847              : */
    1848              : 
    1849            0 : extern "C" void M2CaseList_WriteCase (unsigned int c)
    1850              : {
    1851              :   /* this debugging PROCEDURE should be finished.  */
    1852            0 :   NumberIO_WriteCard (c, 0);
    1853            0 : }
    1854              : 
    1855        14952 : extern "C" void _M2_M2CaseList_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
    1856              : {
    1857        14952 :   caseStack = NULL;
    1858        14952 :   caseId = 0;
    1859        14952 :   caseArray = Indexing_InitIndex (1);
    1860        14952 :   conflictArray = Indexing_InitIndex (1);
    1861        14952 :   FreeRangeList = NULL;
    1862        14952 : }
    1863              : 
    1864            0 : extern "C" void _M2_M2CaseList_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
    1865              : {
    1866            0 : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.