May 06, 2023
https://issues.dlang.org/show_bug.cgi?id=23895

          Issue ID: 23895
           Summary: OOB write in escape analysis code with
                    --preview=dip1021
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: kipthemudkip@yahoo.com

Created attachment 1873
  --> https://issues.dlang.org/attachment.cgi?id=1873&action=edit
Dustmite-reduced reproduction case

I was tracking down compiler weirdness in my codebase while using LDC 1.32.1. Using LDC from my package manager, I'd get a consistent crash, and if I built LDC myself, I'd get an odd error where the compiler said it didn't think a local manifest constant was defined when it certainly was a few lines prior. (Reduced test case for this behavior included.)

Valgrind tells me there was at least one out of bounds write in the escape analysis code. Something is pushed onto an array that was never expanded past its default size of 1.

The crash goes away if I don't compile with --preview=dip1021.

==10074== Invalid write of size 8
==10074==    at 0x60EC8B: Array<VarDeclaration*>::push(VarDeclaration*)
(array.d:120)
==10074==    by 0x70DA7B:
_D3dmd6escape13escapeByValueFCQBc10expression10ExpressionPSQCfQCe15EscapeByResultsbbZ8visitVarMFCQDrQCp6VarExpZv
(escape.d:1543)
==10074==    by 0x649F32:
_D3dmd6escape13escapeByValueFCQBc10expression10ExpressionPSQCfQCe15EscapeByResultsbbZv
(escape.d:1868)
==10074==    by 0x6C12BB:
_D3dmd6escape21checkMutableArgumentsFPSQBl6dscope5ScopeCQCc4func15FuncDeclarationCQDc5mtype12TypeFunctionCQEa10expression10ExpressionPSQFd4root5array__T5ArrayTQCcZQlbZb
(escape.d:171)
==10074==    by 0x6BD1A8:
_D3dmd13expressionsem18functionParametersFKxSQBr8location3LocPSQCj6dscope5ScopeCQDa5mtype12TypeFunctionCQDy10expression10ExpressionCQFaQCa4TypePSQFn4root5array__T5ArrayTQCoZQlCQGs4func15FuncDeclarationPQCtPQDzZb
(expressionsem.d:2455)
==10074==    by 0x6D0B3A: ExpressionSemanticVisitor::visit(CallExp*)
(expressionsem.d:5184)
==10074==    by 0x704717: CallExp::accept(Visitor*) (expression.d:5212)
==10074==    by 0x57171B: expressionSemantic(Expression*, Scope*)
(expressionsem.d:12534)
==10074==    by 0x68E1AD:
_D3dmd7initsem9inferTypeFCQy4init11InitializerPSQBu6dscope5ScopeZ8visitExpMFCQCxQCa14ExpInitializerZQCx
(initsem.d:1158)
==10074==    by 0x68DAF4:
_D3dmd7initsem9inferTypeFCQy4init11InitializerPSQBu6dscope5ScopeZQBo
(initsem.d:1221)
==10074==    by 0x53ED0C: DsymbolSemanticVisitor::visit(VarDeclaration*)
(dsymbolsem.d:494)
==10074==    by 0x53E930:
SemanticTimeTraceVisitor<DsymbolSemanticVisitor*>::visit(VarDeclaration*)
(timetrace_sema.d:108)
==10074==  Address 0x11a8cd58 is 56 bytes inside a block of size 624 free'd
==10074==    at 0x4846CC3: realloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10074==    by 0x56024F: Mem::xrealloc(void*, unsigned long) (rmem.d:85)
==10074==    by 0x6C0DCB:
_D3dmd6escape21checkMutableArgumentsFPSQBl6dscope5ScopeCQCc4func15FuncDeclarationCQDc5mtype12TypeFunctionCQEa10expression10ExpressionPSQFd4root5array__T5ArrayTQCcZQlbZb
(escape.d:103)
==10074==    by 0x6BD1A8:
_D3dmd13expressionsem18functionParametersFKxSQBr8location3LocPSQCj6dscope5ScopeCQDa5mtype12TypeFunctionCQDy10expression10ExpressionCQFaQCa4TypePSQFn4root5array__T5ArrayTQCoZQlCQGs4func15FuncDeclarationPQCtPQDzZb
(expressionsem.d:2455)
==10074==    by 0x6D0B3A: ExpressionSemanticVisitor::visit(CallExp*)
(expressionsem.d:5184)
==10074==    by 0x704717: CallExp::accept(Visitor*) (expression.d:5212)
==10074==    by 0x57171B: expressionSemantic(Expression*, Scope*)
(expressionsem.d:12534)
==10074==    by 0x6CD6B4: ExpressionSemanticVisitor::visit(CallExp*)
(expressionsem.d:4608)
==10074==    by 0x704717: CallExp::accept(Visitor*) (expression.d:5212)
==10074==    by 0x57171B: expressionSemantic(Expression*, Scope*)
(expressionsem.d:12534)
==10074==    by 0x68A2DE:
_D3dmd7initsem19initializerSemanticRCQBj4init11InitializerPSQCg6dscope5ScopeKCQCy5mtype4TypeEQDnQCe13NeedInterpretZ8visitExpMFCQEvQDm14ExpInitializerZQEk
(initsem.d:418)
==10074==    by 0x5841D8: initializerSemantic(Initializer*, Scope*, Type*&,
NeedInterpret) (initsem.d:1059)
==10074==  Block was alloc'd at
==10074==    at 0x4841798: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10074==    by 0x56024F: Mem::xrealloc(void*, unsigned long) (rmem.d:85)
==10074==    by 0x6C0DCB:
_D3dmd6escape21checkMutableArgumentsFPSQBl6dscope5ScopeCQCc4func15FuncDeclarationCQDc5mtype12TypeFunctionCQEa10expression10ExpressionPSQFd4root5array__T5ArrayTQCcZQlbZb
(escape.d:103)
==10074==    by 0x6BD1A8:
_D3dmd13expressionsem18functionParametersFKxSQBr8location3LocPSQCj6dscope5ScopeCQDa5mtype12TypeFunctionCQDy10expression10ExpressionCQFaQCa4TypePSQFn4root5array__T5ArrayTQCoZQlCQGs4func15FuncDeclarationPQCtPQDzZb
(expressionsem.d:2455)
==10074==    by 0x6D0B3A: ExpressionSemanticVisitor::visit(CallExp*)
(expressionsem.d:5184)
==10074==    by 0x704717: CallExp::accept(Visitor*) (expression.d:5212)
==10074==    by 0x57171B: expressionSemantic(Expression*, Scope*)
(expressionsem.d:12534)
==10074==    by 0x5E3E9D: StatementSemanticVisitor::visit(ExpStatement*)
(statementsem.d:206)
==10074==    by 0x608C37: ExpStatement::accept(Visitor*) (statement.d:498)
==10074==    by 0x5E3D3B: statementSemantic(Statement*, Scope*)
(statementsem.d:148)
==10074==    by 0x5E5686: StatementSemanticVisitor::visit(CompoundStatement*)
(statementsem.d:269)
==10074==    by 0x609107: CompoundStatement::accept(Visitor*) (statement.d:641)

--