@@ -3287,8 +3287,8 @@ package body ALI is
-- Acquire (sub)unit and reference file name entries
- Sdep.Table (Sdep.Last).Subunit_Name := No_Name;
- Sdep.Table (Sdep.Last).Unit_Name := No_Name;
+ Sdep.Table (Sdep.Last).Subunit_Name := No_Unit_Name;
+ Sdep.Table (Sdep.Last).Unit_Name := No_Unit_Name;
Sdep.Table (Sdep.Last).Rfile :=
Sdep.Table (Sdep.Last).Sfile;
Sdep.Table (Sdep.Last).Start_Line := 1;
@@ -3304,16 +3304,13 @@ package body ALI is
Add_Char_To_Name_Buffer (Getc);
end loop;
- -- Set the (sub)unit name. Note that we use Name_Find rather
- -- than Name_Enter here as the subunit name may already
- -- have been put in the name table by the Project Manager.
+ -- Set the (sub)unit name.
if Name_Len <= 2
or else Name_Buffer (Name_Len - 1) /= '%'
then
Sdep.Table (Sdep.Last).Subunit_Name := Name_Find;
else
- Name_Len := Name_Len - 2;
Sdep.Table (Sdep.Last).Unit_Name := Name_Find;
end if;
@@ -25,7 +25,7 @@
-- This package defines the internal data structures used for representation
-- of Ada Library Information (ALI) acquired from the ALI files generated by
+-- the front end. The format of the ALI files is documented in Lib.Writ.
with Casing; use Casing;
with Gnatvsn; use Gnatvsn;
@@ -882,11 +882,11 @@ package ALI is
-- Set True for dummy entries that correspond to missing files or files
-- where no dependency relationship exists.
- Subunit_Name : Name_Id;
- -- Name_Id for subunit name if present, else No_Name
+ Subunit_Name : Unit_Name_Type;
+ -- Subunit name if present, else No_Unit_Name
- Unit_Name : Name_Id;
- -- Name_Id for the unit name if not a subunit (No_Name for a subunit)
+ Unit_Name : Unit_Name_Type;
+ -- Unit name if not a subunit (No_Unit_Name for a subunit)
Rfile : File_Name_Type;
-- Reference file name. Same as Sfile unless a Source_Reference pragma
@@ -36,6 +36,7 @@ with Osint;
with Output; use Output;
with Rident; use Rident;
with Types; use Types;
+with Uname;
package body Bcheck is
@@ -68,6 +69,12 @@ package body Bcheck is
-- Used to compare two unit names for No_Dependence checks. U1 is in
-- standard unit name format, and U2 is in literal form with periods.
+ procedure Check_Consistency_Of_Sdep
+ (A : ALIs_Record; D : Sdep_Record; Src : Source_Record);
+ -- Called by Check_Consistency to check the consistency of one Sdep record,
+ -- where A is the ALI, and D represents the unit it depends on, and Src is
+ -- the source file corresponding to D.
+
-------------------------------------
-- Check_Configuration_Consistency --
-------------------------------------
@@ -107,15 +114,129 @@ package body Bcheck is
Check_Consistent_Dispatching_Policy;
end Check_Configuration_Consistency;
+ -------------------------------
+ -- Check_Consistency_Of_Sdep --
+ -------------------------------
+
+ procedure Check_Consistency_Of_Sdep
+ (A : ALIs_Record; D : Sdep_Record; Src : Source_Record)
+ is
+ use Uname;
+ ALI_Path_Id : File_Name_Type;
+ begin
+ -- Check for special case of withing a unit that does not exist any
+ -- more. If the unit was completely missing we would already have
+ -- detected this, but a nasty case arises when we have a subprogram body
+ -- with no spec, and some obsolete unit with's a previous (now
+ -- disappeared) spec. We detect this nasty case by noticing we're
+ -- depending on a spec that has no corresponding unit table entry,
+ -- but the body does.
+
+ if Present (D.Unit_Name)
+ and then Is_Spec_Name (D.Unit_Name)
+ and then Get_Name_Table_Int (D.Unit_Name) = 0 -- no unit table entry?
+ and then Get_Name_Table_Int (Get_Body_Name (D.Unit_Name)) /= 0
+ then
+ Error_Msg_File_1 := A.Sfile;
+ Error_Msg_Unit_1 := D.Unit_Name;
+ Error_Msg ("{ depends on $ which no longer exists");
+ end if;
+
+ -- Now if the time stamps match, or all checksums match, then we are OK;
+ -- otherwise we have an error.
+
+ if D.Stamp /= Src.Stamp and then not Src.All_Checksums_Match then
+ Error_Msg_File_1 := A.Sfile;
+ Error_Msg_File_2 := D.Sfile;
+
+ -- Two styles of message, depending on whether or not
+ -- the updated file is the one that must be recompiled
+
+ if Error_Msg_File_1 = Error_Msg_File_2 then
+ if Tolerate_Consistency_Errors then
+ Error_Msg
+ ("?{ has been modified and should be recompiled");
+ else
+ Error_Msg
+ ("{ has been modified and must be recompiled");
+ end if;
+
+ else
+ ALI_Path_Id :=
+ Osint.Full_Lib_File_Name (A.Afile);
+
+ if Osint.Is_Readonly_Library (ALI_Path_Id) then
+ if Tolerate_Consistency_Errors then
+ Error_Msg ("?{ should be recompiled");
+ Error_Msg_File_1 := ALI_Path_Id;
+ Error_Msg ("?({ is obsolete and read-only)");
+ else
+ Error_Msg ("{ must be compiled");
+ Error_Msg_File_1 := ALI_Path_Id;
+ Error_Msg ("({ is obsolete and read-only)");
+ end if;
+
+ elsif Tolerate_Consistency_Errors then
+ Error_Msg
+ ("?{ should be recompiled ({ has been modified)");
+
+ else
+ Error_Msg ("{ must be recompiled ({ has been modified)");
+ end if;
+ end if;
+
+ if not Tolerate_Consistency_Errors and Verbose_Mode then
+ Error_Msg_File_1 := Src.Stamp_File;
+
+ if Src.Source_Found then
+ Error_Msg_File_1 :=
+ Osint.Full_Source_Name (Error_Msg_File_1);
+ else
+ Error_Msg_File_1 :=
+ Osint.Full_Lib_File_Name (Error_Msg_File_1);
+ end if;
+
+ Error_Msg
+ ("time stamp from { " & String (Src.Stamp));
+
+ Error_Msg_File_1 := D.Sfile;
+ Error_Msg
+ (" conflicts with { timestamp " &
+ String (D.Stamp));
+
+ Error_Msg_File_1 :=
+ Osint.Full_Lib_File_Name (A.Afile);
+ Error_Msg (" from {");
+ end if;
+ end if;
+ end Check_Consistency_Of_Sdep;
+
-----------------------
-- Check_Consistency --
-----------------------
procedure Check_Consistency is
- Src : Source_Id;
- -- Source file Id for this Sdep entry
+ function Reified_Child_Spec (A : ALI_Id; D : Sdep_Id) return Boolean;
+ -- When we have a child subprogram body with no spec, the missing spec
+ -- is reified in the ALI file. This returns True if D is a dependency on
+ -- such a reified spec. The body always immediately follows the spec
+ -- and there is no no unit table entry for the spec in this case.
+ -- We do not want to call Check_Consistency_Of_Sdep for these specs,
+ -- because it confuses the detection of (truly) missing specs.
+
+ function Reified_Child_Spec (A : ALI_Id; D : Sdep_Id) return Boolean is
+ use Uname;
+ begin
+ return Present (Sdep.Table (D).Unit_Name)
+ and then Get_Name_Table_Int (Sdep.Table (D).Unit_Name) = 0
+ and then D /= ALIs.Table (A).Last_Sdep
+ and then Sdep.Table (D).Sfile = Sdep.Table (D + 1).Sfile
+ and then Is_Spec_Name (Sdep.Table (D).Unit_Name)
+ and then Get_Body_Name (Sdep.Table (D).Unit_Name) =
+ Sdep.Table (D + 1).Unit_Name;
+ end Reified_Child_Spec;
- ALI_Path_Id : File_Name_Type;
+ -- Start of processing for Check_Consistency
begin
-- First, we go through the source table to see if there are any cases
@@ -172,89 +293,14 @@ package body Bcheck is
Sdep_Loop : for D in
ALIs.Table (A).First_Sdep .. ALIs.Table (A).Last_Sdep
loop
- if Sdep.Table (D).Dummy_Entry then
- goto Continue;
- end if;
-
- Src := Source_Id (Get_Name_Table_Int (Sdep.Table (D).Sfile));
-
- -- If the time stamps match, or all checksums match, then we
- -- are OK, otherwise we have a definite error.
-
- if Sdep.Table (D).Stamp /= Source.Table (Src).Stamp
- and then not Source.Table (Src).All_Checksums_Match
+ if not Sdep.Table (D).Dummy_Entry
+ and then not Reified_Child_Spec (A, D)
then
- Error_Msg_File_1 := ALIs.Table (A).Sfile;
- Error_Msg_File_2 := Sdep.Table (D).Sfile;
-
- -- Two styles of message, depending on whether or not
- -- the updated file is the one that must be recompiled
-
- if Error_Msg_File_1 = Error_Msg_File_2 then
- if Tolerate_Consistency_Errors then
- Error_Msg
- ("?{ has been modified and should be recompiled");
- else
- Error_Msg
- ("{ has been modified and must be recompiled");
- end if;
-
- else
- ALI_Path_Id :=
- Osint.Full_Lib_File_Name (ALIs.Table (A).Afile);
-
- if Osint.Is_Readonly_Library (ALI_Path_Id) then
- if Tolerate_Consistency_Errors then
- Error_Msg ("?{ should be recompiled");
- Error_Msg_File_1 := ALI_Path_Id;
- Error_Msg ("?({ is obsolete and read-only)");
- else
- Error_Msg ("{ must be compiled");
- Error_Msg_File_1 := ALI_Path_Id;
- Error_Msg ("({ is obsolete and read-only)");
- end if;
-
- elsif Tolerate_Consistency_Errors then
- Error_Msg
- ("?{ should be recompiled ({ has been modified)");
-
- else
- Error_Msg ("{ must be recompiled ({ has been modified)");
- end if;
- end if;
-
- if not Tolerate_Consistency_Errors and Verbose_Mode then
- Error_Msg_File_1 := Source.Table (Src).Stamp_File;
-
- if Source.Table (Src).Source_Found then
- Error_Msg_File_1 :=
- Osint.Full_Source_Name (Error_Msg_File_1);
- else
- Error_Msg_File_1 :=
- Osint.Full_Lib_File_Name (Error_Msg_File_1);
- end if;
-
- Error_Msg
- ("time stamp from { " & String (Source.Table (Src).Stamp));
-
- Error_Msg_File_1 := Sdep.Table (D).Sfile;
- Error_Msg
- (" conflicts with { timestamp " &
- String (Sdep.Table (D).Stamp));
-
- Error_Msg_File_1 :=
- Osint.Full_Lib_File_Name (ALIs.Table (A).Afile);
- Error_Msg (" from {");
- end if;
-
- -- Exit from the loop through Sdep entries once we find one
- -- that does not match.
-
- exit Sdep_Loop;
+ Check_Consistency_Of_Sdep
+ (ALIs.Table (A), Sdep.Table (D),
+ Source.Table
+ (Source_Id (Get_Name_Table_Int (Sdep.Table (D).Sfile))));
end if;
-
- <<Continue>>
- null;
end loop Sdep_Loop;
end loop ALIs_Loop;
end Check_Consistency;
@@ -1263,7 +1309,7 @@ package body Bcheck is
procedure Check_Duplicated_Subunits is
begin
for J in Sdep.First .. Sdep.Last loop
- if Sdep.Table (J).Subunit_Name /= No_Name then
+ if Sdep.Table (J).Subunit_Name /= No_Unit_Name then
Get_Decoded_Name_String (Sdep.Table (J).Subunit_Name);
Name_Len := Name_Len + 2;
Name_Buffer (Name_Len - 1) := '%';
@@ -2334,7 +2334,7 @@ package body Binde is
for J in Sdep.First .. Sdep.Last loop
Source := Sdep.Table (J).Sfile;
- if Sdep.Table (J).Subunit_Name /= No_Name
+ if Sdep.Table (J).Subunit_Name /= No_Unit_Name
and then Put_In_Sources (Source)
and then not Is_Internal_File_Name (Source)
then
@@ -248,7 +248,7 @@ package body Clean is
for J in ALIs.Table (The_ALI).First_Sdep ..
ALIs.Table (The_ALI).Last_Sdep
loop
- if Sdep.Table (J).Subunit_Name /= No_Name then
+ if Sdep.Table (J).Subunit_Name /= No_Unit_Name then
Sources.Increment_Last;
Sources.Table (Sources.Last) :=
Sdep.Table (J).Sfile;
From: Bob Duff <duff@adacore.com> If a subprogram spec S is present while compiling something that says "with S;", but the spec is absent while compiling the body of S, then gnatbind fails to detect the mismatch. The spec and body of S might have different parameter and result types. This patch fixes gnatbind to detect this case and give an error. gcc/ada/ * bcheck.adb (Check_Consistency_Of_Sdep): Split out new procedure. Add check for special case of subprogram spec that no longer exists. (Check_Consistency): Call Check_Consistency_Of_Sdep, except when Reified_Child_Spec is True. No need for "goto Continue" or "exit Sdep_Loop". * ali.ads (Subunit_Name, Unit_Name): Change the type to Unit_Name_Type. Add a comment pointing to the ALI file documentation, because it's in a somewhat-surprising place. * ali.adb (Scan_ALI): Subunit_Name and Unit_Name are now Unit_Name_Type. Remove comment explaining why Name_Find is used; Name_Find is the usual case. Do not remove the "%s" or "%b" from the Unit_Name. We need to be able to distinguish specs and bodies. This is also necessary to obey the invariant of Unit_Name_Type. * binde.adb (Write_Closure): Subunit_Name is now Unit_Name_Type. * clean.adb (Clean_Executables): Likewise. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/ali.adb | 9 +- gcc/ada/ali.ads | 10 +-- gcc/ada/bcheck.adb | 216 +++++++++++++++++++++++++++------------------ gcc/ada/binde.adb | 2 +- gcc/ada/clean.adb | 2 +- 5 files changed, 141 insertions(+), 98 deletions(-)