@@ -2569,7 +2569,7 @@ void PseudoCFunction::GetExprTextInternal(const HighLevelILInstruction& instr, H
25692569 if (type && (type->GetClass () == NamedTypeReferenceClass))
25702570 type = GetFunction ()->GetView ()->GetTypeByRef (type->GetNamedTypeReference ());
25712571
2572- bool derefOffset = false ;
2572+ // Handle structure member access
25732573 if (type && (type->GetClass () == StructureTypeClass))
25742574 {
25752575 std::optional<size_t > memberIndexHint;
@@ -2610,51 +2610,62 @@ void PseudoCFunction::GetExprTextInternal(const HighLevelILInstruction& instr, H
26102610 memberIndexHint)
26112611 return ;
26122612 }
2613- else if (type && (type->GetClass () == StructureTypeClass))
2613+
2614+ // For non-struct types or when struct member resolution fails,
2615+ // render as pointer arithmetic: *[(type*)]([(char*)]expr[ + offset])
2616+ bool hasOffset = offset != 0 ;
2617+ bool needsOuterParens = precedence > UnaryOperatorPrecedence;
2618+ bool showTypeCasts = !settings || settings->IsOptionSet (ShowTypeCasts);
2619+
2620+ if (needsOuterParens)
2621+ tokens.AppendOpenParen ();
2622+
2623+ tokens.Append (OperationToken, " *" );
2624+
2625+ // Skip the outer cast if we're dereferencing a single byte and are
2626+ // already casting to char* for the pointer arithmetic
2627+ bool skipOuterCast = hasOffset && instr.size == 1 ;
2628+ if (showTypeCasts && !skipOuterCast)
26142629 {
2615- derefOffset = true ;
2630+ tokens.AppendOpenParen ();
2631+ AppendSizeToken (hasOffset && type ? srcExpr.size : instr.size , true , tokens);
2632+ tokens.Append (TextToken, " *" );
2633+ tokens.AppendCloseParen ();
26162634 }
26172635
2618- if (derefOffset || offset != 0 )
2636+ if (hasOffset )
26192637 {
2620- bool parens = precedence > UnaryOperatorPrecedence;
2621- if (parens)
2622- tokens.AppendOpenParen ();
2623-
2624- tokens.Append (OperationToken, " *" );
2625- if (!settings || settings->IsOptionSet (ShowTypeCasts))
2626- {
2627- tokens.AppendOpenParen ();
2628- AppendSizeToken (!derefOffset ? srcExpr.size : instr.size , true , tokens);
2629- tokens.Append (TextToken, " *" );
2630- tokens.AppendCloseParen ();
2631- }
26322638 tokens.AppendOpenParen ();
2633- if (!settings || settings-> IsOptionSet (ShowTypeCasts) )
2639+ if (showTypeCasts )
26342640 {
26352641 tokens.AppendOpenParen ();
26362642 tokens.Append (TypeNameToken, " char" );
26372643 tokens.Append (TextToken, " *" );
26382644 tokens.AppendCloseParen ();
26392645 }
2646+ }
26402647
2641- if (srcExpr.operation == HLIL_CONST_PTR)
2642- {
2643- const auto constant = srcExpr.GetConstant <HLIL_CONST_PTR>();
2644- tokens.AppendPointerTextToken (srcExpr, constant, settings, DisplaySymbolOnly, precedence);
2645- }
2646- else
2647- {
2648- GetExprTextInternal (srcExpr, tokens, settings, AddOperatorPrecedence);
2649- }
2648+ if (srcExpr.operation == HLIL_CONST_PTR)
2649+ {
2650+ const auto constant = srcExpr.GetConstant <HLIL_CONST_PTR>();
2651+ tokens.AppendPointerTextToken (srcExpr, constant, settings, DisplaySymbolOnly, precedence);
2652+ }
2653+ else
2654+ {
2655+ GetExprTextInternal (srcExpr, tokens, settings,
2656+ hasOffset ? AddOperatorPrecedence : UnaryOperatorPrecedence);
2657+ }
26502658
2659+ if (hasOffset)
2660+ {
26512661 tokens.Append (OperationToken, " + " );
26522662 tokens.AppendIntegerTextToken (instr, offset, instr.size );
26532663 tokens.AppendCloseParen ();
2654- if (parens)
2655- tokens.AppendCloseParen ();
26562664 }
26572665
2666+ if (needsOuterParens)
2667+ tokens.AppendCloseParen ();
2668+
26582669 if (statement)
26592670 tokens.AppendSemicolon ();
26602671 }();
0 commit comments