From 497c830603c7ef1b67a0e3c8e5ab6aadb98c0c44 Mon Sep 17 00:00:00 2001 From: Mattias Gaertner Date: Fri, 16 Aug 2019 07:28:09 +0000 Subject: [PATCH] fcl-passrc: check used unit reference for duplicate, in case unit is found via different names git-svn-id: trunk@42704 - --- packages/fcl-passrc/src/pparser.pp | 27 +++++++++++++++++++----- packages/fcl-passrc/tests/tcresolver.pas | 23 ++++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/packages/fcl-passrc/src/pparser.pp b/packages/fcl-passrc/src/pparser.pp index eb9cdd4168..e011191813 100644 --- a/packages/fcl-passrc/src/pparser.pp +++ b/packages/fcl-passrc/src/pparser.pp @@ -3750,7 +3750,7 @@ function TPasParser.AddUseUnit(ASection: TPasSection; const NamePos: TPasSourcePos; AUnitName: string; NameExpr: TPasExpr; InFileExpr: TPrimitiveExpr): TPasUsesUnit; - procedure CheckDuplicateInUsesList(AUnitName : string; UsesClause: TPasUsesClause); + procedure CheckDuplicateInUsesList(UsesClause: TPasUsesClause); var i: Integer; begin @@ -3760,6 +3760,16 @@ function TPasParser.AddUseUnit(ASection: TPasSection; ParseExc(nParserDuplicateIdentifier,SParserDuplicateIdentifier,[AUnitName]); end; + procedure CheckDuplicateInUsesList(UnitRef: TPasElement; UsesClause: TPasUsesClause); + var + i: Integer; + begin + if UsesClause=nil then exit; + for i:=0 to length(UsesClause)-1 do + if UsesClause[i].Module=UnitRef then + ParseExc(nParserDuplicateIdentifier,SParserDuplicateIdentifier,[AUnitName]); + end; + var UnitRef: TPasElement; UsesUnit: TPasUsesUnit; @@ -3777,16 +3787,23 @@ begin exit; // for compatibility ignore implicit use of system in system ParseExc(nParserDuplicateIdentifier,SParserDuplicateIdentifier,[AUnitName]); end; - CheckDuplicateInUsesList(AUnitName,ASection.UsesClause); - if ASection.ClassType=TImplementationSection then - CheckDuplicateInUsesList(AUnitName,CurModule.InterfaceSection.UsesClause); UnitRef := Engine.FindModule(AUnitName,NameExpr,InFileExpr); if Assigned(UnitRef) then - UnitRef.AddRef{$IFDEF CheckPasTreeRefCount}('TPasUsesUnit.Module'){$ENDIF} + begin + UnitRef.AddRef{$IFDEF CheckPasTreeRefCount}('TPasUsesUnit.Module'){$ENDIF}; + CheckDuplicateInUsesList(UnitRef,ASection.UsesClause); + if ASection.ClassType=TImplementationSection then + CheckDuplicateInUsesList(UnitRef,CurModule.InterfaceSection.UsesClause); + end else + begin + CheckDuplicateInUsesList(ASection.UsesClause); + if ASection.ClassType=TImplementationSection then + CheckDuplicateInUsesList(CurModule.InterfaceSection.UsesClause); UnitRef := TPasUnresolvedUnitRef(CreateElement(TPasUnresolvedUnitRef, AUnitName, ASection, NamePos)); + end; UsesUnit:=TPasUsesUnit(CreateElement(TPasUsesUnit,AUnitName,ASection,NamePos)); Result:=ASection.AddUnitToUsesList(AUnitName,NameExpr,InFileExpr,UnitRef,UsesUnit); diff --git a/packages/fcl-passrc/tests/tcresolver.pas b/packages/fcl-passrc/tests/tcresolver.pas index 43c2e77a46..d948d841f0 100644 --- a/packages/fcl-passrc/tests/tcresolver.pas +++ b/packages/fcl-passrc/tests/tcresolver.pas @@ -360,6 +360,7 @@ type Procedure TestUnitUseIntf; Procedure TestUnitUseImplFail; Procedure TestUnit_DuplicateUsesFail; + Procedure TestUnit_DuplicateUsesIntfImplFail; Procedure TestUnit_NestedFail; Procedure TestUnitUseDotted; Procedure TestUnit_ProgramDefaultNamespace; @@ -5674,6 +5675,28 @@ begin nParserDuplicateIdentifier); end; +procedure TTestResolver.TestUnit_DuplicateUsesIntfImplFail; +begin + AddModuleWithIntfImplSrc('unit2.pp', + LinesToStr([ + 'type number = longint;']), + LinesToStr([ + ''])); + + StartUnit(true); + Add([ + 'interface', + 'uses unit2;', + 'var j: number;', + 'implementation', + 'uses unit2;', + 'initialization', + ' if number(3) then ;', + '']); + CheckParserException('Duplicate identifier "unit2" at token ";" in file afile.pp at line 6 column 11', + nParserDuplicateIdentifier); +end; + procedure TTestResolver.TestUnit_NestedFail; begin AddModuleWithIntfImplSrc('unit2.pp',