fcl-passrc: check used unit reference for duplicate, in case unit is found via different names

git-svn-id: trunk@42704 -
This commit is contained in:
Mattias Gaertner 2019-08-16 07:28:09 +00:00
parent 8ad47efcb3
commit 497c830603
2 changed files with 45 additions and 5 deletions

View File

@ -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);

View File

@ -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',