Skip to content

Commit f243074

Browse files
author
Eric Botcazou
committed
Ada: Fix variable initialized with if-expression not flagged as constant
This is a regression present on the mainline and 15 branch: the -gnatwk switch no longer flags a string variable initialized with an if-expression as constant when it is not modified in the program. The fix is to set the Has_Initial_Value and Never_Set_In_Source flags earlier during analysis in the Analyze_Object_Declaration procedure. gcc/ada/ PR ada/122640 * sem_ch3.adb (Analyze_Object_Declaration): Set Is_True_Constant on entry for constants and Never_Set_In_Source in all cases. If an initialization expression is present, set Has_Initial_Value and Is_True_Constant on variables. gcc/testsuite/ * gnat.dg/warn34.adb: New test.
1 parent 5fac2f4 commit f243074

File tree

2 files changed

+39
-45
lines changed

2 files changed

+39
-45
lines changed

gcc/ada/sem_ch3.adb

Lines changed: 30 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4365,10 +4365,17 @@ package body Sem_Ch3 is
43654365
begin
43664366
if Constant_Present (N) then
43674367
Mutate_Ekind (Id, E_Constant);
4368+
Set_Is_True_Constant (Id);
43684369
else
43694370
Mutate_Ekind (Id, E_Variable);
43704371
end if;
43714372

4373+
-- Indicate this is not set in source. Certainly true for constants, and
4374+
-- true for variables so far (will be reset for a variable if and when
4375+
-- we encounter a modification in the source).
4376+
4377+
Set_Never_Set_In_Source (Id);
4378+
43724379
-- There are three kinds of implicit types generated by an
43734380
-- object declaration:
43744381

@@ -4649,17 +4656,23 @@ package body Sem_Ch3 is
46494656
Set_Etype (E, T);
46504657
end if;
46514658

4652-
-- If an initialization expression is present, then we set the
4653-
-- Is_True_Constant flag. It will be reset if this is a variable
4654-
-- and it is indeed modified.
4655-
4656-
Set_Is_True_Constant (Id, True);
4657-
46584659
-- If we are analyzing a constant declaration, set its completion
46594660
-- flag after analyzing and resolving the expression.
46604661

46614662
if Constant_Present (N) then
46624663
Set_Has_Completion (Id);
4664+
4665+
-- Set Has_Initial_Value if initialization expression present. Note
4666+
-- that if there is no initializing expression, we leave the state
4667+
-- of this flag unchanged (usually it will be False, but notably in
4668+
-- the case of exception choice variables, it will already be true).
4669+
4670+
-- Set Is_True_Constant if initialization expression is present. It
4671+
-- will be reset if the variable is indeed modified.
4672+
4673+
else
4674+
Set_Has_Initial_Value (Id);
4675+
Set_Is_True_Constant (Id);
46634676
end if;
46644677

46654678
-- Set type and resolve (type may be overridden later on). Note:
@@ -5070,15 +5083,6 @@ package body Sem_Ch3 is
50705083
-- that subsequent uses of this entity are not rejected
50715084
-- via the same mechanism that (correctly) rejects
50725085
-- "X : Integer := X;".
5073-
5074-
if Constant_Present (N) then
5075-
Set_Is_True_Constant (Id);
5076-
else
5077-
if Present (E) then
5078-
Set_Has_Initial_Value (Id);
5079-
end if;
5080-
end if;
5081-
50825086
goto Leave;
50835087
end if;
50845088

@@ -5202,43 +5206,24 @@ package body Sem_Ch3 is
52025206

52035207
Check_Wide_Character_Restriction (T, Object_Definition (N));
52045208

5205-
-- Indicate this is not set in source. Certainly true for constants, and
5206-
-- true for variables so far (will be reset for a variable if and when
5207-
-- we encounter a modification in the source).
5208-
5209-
Set_Never_Set_In_Source (Id);
5210-
52115209
-- Now establish the proper kind and type of the object
52125210

52135211
if Ekind (Id) = E_Void then
52145212
Reinit_Field_To_Zero (Id, F_Next_Inlined_Subprogram);
52155213
end if;
52165214

5217-
if Constant_Present (N) then
5218-
Set_Is_True_Constant (Id);
5215+
-- A variable is set as shared passive if it appears in a shared
5216+
-- passive package, and is at the outer level. This is not done for
5217+
-- entities generated during expansion, because those are always
5218+
-- manipulated locally.
52195219

5220-
else
5221-
-- A variable is set as shared passive if it appears in a shared
5222-
-- passive package, and is at the outer level. This is not done for
5223-
-- entities generated during expansion, because those are always
5224-
-- manipulated locally.
5225-
5226-
if Is_Shared_Passive (Current_Scope)
5227-
and then Is_Library_Level_Entity (Id)
5228-
and then Comes_From_Source (Id)
5229-
then
5230-
Set_Is_Shared_Passive (Id);
5231-
Check_Shared_Var (Id, T, N);
5232-
end if;
5233-
5234-
-- Set Has_Initial_Value if initializing expression present. Note
5235-
-- that if there is no initializing expression, we leave the state
5236-
-- of this flag unchanged (usually it will be False, but notably in
5237-
-- the case of exception choice variables, it will already be true).
5238-
5239-
if Present (E) then
5240-
Set_Has_Initial_Value (Id);
5241-
end if;
5220+
if not Constant_Present (N)
5221+
and then Is_Shared_Passive (Current_Scope)
5222+
and then Is_Library_Level_Entity (Id)
5223+
and then Comes_From_Source (Id)
5224+
then
5225+
Set_Is_Shared_Passive (Id);
5226+
Check_Shared_Var (Id, T, N);
52425227
end if;
52435228

52445229
-- Set the SPARK mode from the current context (may be overwritten later

gcc/testsuite/gnat.dg/warn34.adb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-- { dg-do compile }
2+
-- { dg-options "-gnatwk" }
3+
4+
function Warn34 (F : Boolean) return String is
5+
S : String := -- { dg-warning "could be declared constant" }
6+
(if F then "foo" else "bar");
7+
begin
8+
return S;
9+
end;

0 commit comments

Comments
 (0)