From 4d216619502c0cabaab77e2e2a15b4800e61a042 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 17 Nov 2024 23:13:57 +0100 Subject: [PATCH] FpDebug: improve handling enum with negative ord value. --- components/fpdebug/fpdbgdwarf.pas | 13 ++- .../lazdebuggerfp/test/testwatches.pas | 85 +++++++++++++++++- .../lazdebuggers/lazdebugtestbase/sources.res | Bin 127560 -> 128300 bytes .../testapps/WatchesValuePrg.pas | 8 ++ .../testapps/WatchesValuePrgIdent.inc | 7 ++ 5 files changed, 109 insertions(+), 4 deletions(-) diff --git a/components/fpdebug/fpdbgdwarf.pas b/components/fpdebug/fpdbgdwarf.pas index c4d7fe913b..083cb818b6 100644 --- a/components/fpdebug/fpdbgdwarf.pas +++ b/components/fpdebug/fpdbgdwarf.pas @@ -2999,17 +2999,26 @@ end; procedure TFpValueDwarfEnum.InitMemberIndex; var v: QWord; - i: Integer; + v2: Int64; + i, j: Integer; begin // TODO: if TypeInfo is a subrange, check against the bounds, then bypass it, and scan all members (avoid subrange scanning members) if FMemberValueDone then exit; // FTypeSymbol (if not nil) must be same as FTypeSymbol. It may have wrappers like declaration. v := GetAsCardinal; + v2 := GetAsInteger; i := FTypeSymbol.NestedSymbolCount - 1; + j := -1; while i >= 0 do begin - if FTypeSymbol.NestedSymbol[i].OrdinalValue = v then break; + if QWord(FTypeSymbol.NestedSymbol[i].OrdinalValue) = v then + break; + if FTypeSymbol.NestedSymbol[i].OrdinalValue = v2 then + j := i; dec(i); end; + // If the value was not found, then fall back to a signed (possible sign extended) comparison + if i < 0 then + i := j; FMemberIndex := i; FMemberValueDone := True; end; diff --git a/components/lazdebuggers/lazdebuggerfp/test/testwatches.pas b/components/lazdebuggers/lazdebuggerfp/test/testwatches.pas index b538905158..1740ef07d0 100644 --- a/components/lazdebuggers/lazdebuggerfp/test/testwatches.pas +++ b/components/lazdebuggers/lazdebuggerfp/test/testwatches.pas @@ -1062,6 +1062,13 @@ t.Add(AName, p+'FiveDynArray'+e+'[0]', weMatch('.*',skRecord)); t.Add(AName, p+'Enum2'+e, weEnum('EnVal21', 'TEnum2')); t.Add(AName, p+'Enum3'+e, weEnum('EnVal25', 'TEnum2')); + t.Add(AName, p+'EnumX0a'+e, weEnum('EnXVal01', 'TEnumX0')); + t.Add(AName, p+'EnumX0b'+e, weEnum('EnXVal04', 'TEnumX0')); + t.Add(AName, p+'EnumX1a'+e, weEnum('EnXVal11', 'TEnumX1')); + t.Add(AName, p+'EnumX1b'+e, weEnum('EnXVal14', 'TEnumX1')); + t.Add(AName, p+'EnumX2a'+e, weEnum('EnXVal21', 'TEnumX2')); + t.Add(AName, p+'EnumX2b'+e, weEnum('EnXVal24', 'TEnumX2')); + // t.Add(AName, 'EnVal2', weMatch('xxx', skEnumValue)); t.Add(AName, p+'Enum16'+e, weEnum('ExVal23', 'TEnum16')); @@ -1413,6 +1420,13 @@ begin t.Add('EnVal21', 'EnVal21', weMatch('EnVal21 *:?= *3', skEnumValue)); t.Add('EnVal23', 'EnVal23', weMatch('EnVal23 *:?= *7', skEnumValue)); + t.Add('EnXVal01', 'EnXVal01', weMatch('EnXVal01 *:?= *-503', skEnumValue)); + t.Add('EnXVal04', 'EnXVal04', weMatch('EnXVal04 *:?= *510', skEnumValue)); + t.Add('EnXVal11', 'EnXVal11', weMatch('EnXVal11 *:?= *-3', skEnumValue)); + t.Add('EnXVal14', 'EnXVal14', weMatch('EnXVal14 *:?= *10', skEnumValue)); + t.Add('EnXVal21', 'EnXVal21', weMatch('EnXVal21 *:?= *-203', skEnumValue)); + t.Add('EnXVal24', 'EnXVal24', weMatch('EnXVal24 *:?= *210', skEnumValue)); + // recurse pointers // TODO: currently just run them and check they do not fail,crash or hang. // TODO: add checks for result @@ -3906,8 +3920,8 @@ procedure TTestWatches.TestWatchesExpression; APrefix2: String; AOffs2: Integer; AChr12: Char; APostFix2: String; ALoc2: TTestLoc ); var - p, e, p2, e2: String; - n, i, n2: Integer; + p, e, p2, e2, enx01, enx02: String; + n, i, j, n2: Integer; begin p := APrefix; e := APostFix; @@ -4036,6 +4050,73 @@ procedure TTestWatches.TestWatchesExpression; t.Add('ENUM-Cmp: ', p+'Enum > TEnum(1)', weBool(True)); t.Add('ENUM-Cmp: ', p+'Enum > TEnum(-1)', weBool(True)); + for i := 0 to 39 do + for j := 0 to 39 do begin + case i of + 0..3: enx01 := 'TEnumX0(-504)'; + 4: enx01 := 'TEnumX0(-503)'; 5: enx01 := 'EnXVal01'; 6..7: enx01 := p+'EnumX0a'; + 8..11: enx01 := 'TEnumX0(-502)'; + 12..15: enx01 := 'TEnumX0(-1)'; + 16..19: enx01 := 'TEnumX0(0)'; + 20..23: enx01 := 'TEnumX0(1)'; + 24: enx01 := 'TEnumX0(4)'; 25..27: enx01 := 'EnXVal02'; + 28: enx01 := 'TEnumX0(7)'; 29..31: enx01 := 'EnXVal03'; + 32: enx01 := 'TEnumX0(510)'; 33: enx01 := 'EnXVal04'; 34..35: enx01 := p+'EnumX0b'; + 36..39: enx01 := 'TEnumX0(5000)'; + end; + case j of + 0..3: enx02 := 'TEnumX0(-504)'; + 4: enx02 := 'TEnumX0(-503)'; 5: enx02 := 'EnXVal01'; 6..7: enx02 := p+'EnumX0a'; + 8..11: enx02 := 'TEnumX0(-502)'; + 12..15: enx02 := 'TEnumX0(-1)'; + 16..19: enx02 := 'TEnumX0(0)'; + 20..23: enx02 := 'TEnumX0(1)'; + 24: enx02 := 'TEnumX0(4)'; 25..27: enx02 := 'EnXVal02'; + 28: enx02 := 'TEnumX0(7)'; 29..31: enx02 := 'EnXVal03'; + 32: enx02 := 'TEnumX0(510)'; 33: enx02 := 'EnXVal04'; 34..35: enx02 := p+'EnumX0b'; + 36..39: enx02 := 'TEnumX0(5000)'; + end; + + + t.Add('Signed ENUM-Cmp: ', enx01+' > '+enx02, weBool((i and $FFFC) > (j and $FFFC))); + t.Add('Signed ENUM-Cmp: ', enx01+' < '+enx02, weBool((i and $FFFC) < (j and $FFFC))); + t.Add('Signed ENUM-Cmp: ', enx01+' <> '+enx02, weBool((i and $FFFC) <> (j and $FFFC))); + t.Add('Signed ENUM-Cmp: ', enx01+' = '+enx02, weBool((i and $FFFC) = (j and $FFFC))); + end; + + for i := 0 to 39 do + for j := 0 to 39 do begin + case i of + 0..3: enx01 := 'TEnumX1(-4)'; + 4: enx01 := 'TEnumX1(-3)'; 5: enx01 := 'EnXVal11'; 6..7: enx01 := p+'EnumX1a'; + 8..11: enx01 := 'TEnumX1(-2)'; + 12..15: enx01 := 'TEnumX1(-1)'; + 16..19: enx01 := 'TEnumX1(0)'; + 20..23: enx01 := 'TEnumX1(1)'; + 24: enx01 := 'TEnumX1(4)'; 25..27: enx01 := 'EnXVal12'; + 28: enx01 := 'TEnumX1(7)'; 29..31: enx01 := 'EnXVal13'; + 32: enx01 := 'TEnumX1(10)'; 33: enx01 := 'EnXVal14'; 34..35: enx01 := p+'EnumX1b'; + 36..39: enx01 := 'TEnumX1(50)'; + end; + case j of + 0..3: enx02 := 'TEnumX1(-4)'; + 4: enx02 := 'TEnumX1(-3)'; 5: enx02 := 'EnXVal11'; 6..7: enx02 := p+'EnumX1a'; + 8..11: enx02 := 'TEnumX1(-2)'; + 12..15: enx02 := 'TEnumX1(-1)'; + 16..19: enx02 := 'TEnumX1(0)'; + 20..23: enx02 := 'TEnumX1(1)'; + 24: enx02 := 'TEnumX1(4)'; 25..27: enx02 := 'EnXVal12'; + 28: enx02 := 'TEnumX1(7)'; 29..31: enx02 := 'EnXVal13'; + 32: enx02 := 'TEnumX1(10)'; 33: enx02 := 'EnXVal14'; 34..35: enx02 := p+'EnumX1b'; + 36..39: enx02 := 'TEnumX1(50)'; + end; + + + t.Add('Signed ENUM-Cmp: ', enx01+' > '+enx02, weBool((i and $FFFC) > (j and $FFFC))); + t.Add('Signed ENUM-Cmp: ', enx01+' < '+enx02, weBool((i and $FFFC) < (j and $FFFC))); + t.Add('Signed ENUM-Cmp: ', enx01+' <> '+enx02, weBool((i and $FFFC) <> (j and $FFFC))); + t.Add('Signed ENUM-Cmp: ', enx01+' = '+enx02, weBool((i and $FFFC) = (j and $FFFC))); + end; for i := 0 to t.Count-1 do t.Tests[i].IgnTypeName(); diff --git a/components/lazdebuggers/lazdebugtestbase/sources.res b/components/lazdebuggers/lazdebugtestbase/sources.res index 6b70067fe174b980b85f31cf22fd432268151e31..20501785dd454a37eb4b9e997ae4d45eff4951bd 100644 GIT binary patch delta 670 zcmX@{gni8`_6>JbnSOlRd{32AuiiDUG&jOP!B#=TH7_D8F~`8rRzcU)z*t8C$~UrA zFoAQ7Z57Pn91~jwQ$qtyYhEq|g=&?6#N=#{VG4$|Ab}9D!G;Kf4S@zLDCoisHUt}7 z54FY+*IcZ=2e8~F0^{|w-X#exv;0&X$OZuP)c^ocli?*Lw?Z8O)s(mAvjIgx D0Xh`r diff --git a/components/lazdebuggers/lazdebugtestbase/testapps/WatchesValuePrg.pas b/components/lazdebuggers/lazdebugtestbase/testapps/WatchesValuePrg.pas index 27f465d9d4..20445d3f06 100644 --- a/components/lazdebuggers/lazdebugtestbase/testapps/WatchesValuePrg.pas +++ b/components/lazdebuggers/lazdebugtestbase/testapps/WatchesValuePrg.pas @@ -274,6 +274,14 @@ type E8Val50, E8Val51, E8Val52, E8Val53, E8Val54, E8Val55, E8Val56, E8Val57, E8Val58, E8Val59, E8Val5A, E8Val5B ); + TEnumX0 = (EnXVal01= -503, EnXVal02= 4, EnXVal03= 7, EnXVal04= 510); + {$PackEnum 1} + TEnumX1 = (EnXVal11= -3, EnXVal12= 4, EnXVal13= 7, EnXVal14= 10); + {$PackEnum 2} + TEnumX2 = (EnXVal21= -203, EnXVal22= 4, EnXVal23= 7, EnXVal24= 210); + {$PackEnum default} + + TSet = set of TEnum; TSet3 = set of TEnum3; TSmallRangeSet = set of TSmallRange; diff --git a/components/lazdebuggers/lazdebugtestbase/testapps/WatchesValuePrgIdent.inc b/components/lazdebuggers/lazdebugtestbase/testapps/WatchesValuePrgIdent.inc index aaec28a6a1..b1860657ce 100644 --- a/components/lazdebuggers/lazdebugtestbase/testapps/WatchesValuePrgIdent.inc +++ b/components/lazdebuggers/lazdebugtestbase/testapps/WatchesValuePrgIdent.inc @@ -421,6 +421,13 @@ pre__Enum16{e} _OP_ TEnum16(ExVal23); //@@ _pre3_Enum16{e3}; pre__Enum16A{e} _OP_ TEnum16(ExValX5); //@@ _pre3_Enum16A{e3}; + pre__EnumX0a{e} _OP_ TEnumX0(EnXVal01); //@@ _pre3_EnumX0a{e3}; + pre__EnumX0b{e} _OP_ TEnumX0(EnXVal04); //@@ _pre3_EnumX0b{e3}; + pre__EnumX1a{e} _OP_ TEnumX1(EnXVal11); //@@ _pre3_EnumX1a{e3}; + pre__EnumX1b{e} _OP_ TEnumX1(EnXVal14); //@@ _pre3_EnumX1b{e3}; + pre__EnumX2a{e} _OP_ TEnumX2(EnXVal21); //@@ _pre3_EnumX2a{e3}; + pre__EnumX2b{e} _OP_ TEnumX2(EnXVal24); //@@ _pre3_EnumX2b{e3}; + pre__Set{e} _OP_ TSet([EnVal2, EnVal4]); //@@ _pre3_Set{e3}; pre__SmallSet{e} _OP_ TSmallRangeSet([22, 24,25]); //@@ _pre3_SmallSet{e3};