diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-08-29 12:37:05 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-08-29 12:37:05 +0000 |
commit | 12cb78d1cca1387a092ec0bd49c250340bff4afc (patch) | |
tree | 1eab97da96906e0a2786d51d9f25f20de02befcf /gcc/ada/sem_eval.adb | |
parent | 31879e18aea3222fe3e56f2c0319c9f230645ff3 (diff) | |
download | gcc-12cb78d1cca1387a092ec0bd49c250340bff4afc.tar.gz |
2012-08-29 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 190745 using svnmerge, notably
C++ conversion.
[gcc/]
2012-08-29 Basile Starynkevitch <basile@starynkevitch.net>
{{merging with trunk, converted to C++}}
* melt-runtime.h (MELT_FLEXIBLE_DIM): Set when C++.
* melt-runtime.c (melt_tempdir_path): Don't use choose_tmpdir from
libiberty.
(meltgc_start_module_by_index): Use address-of & on VEC_index.
(melt_really_initialize): When printing builtin settings, handle
GCC 4.8 as with implicit ENABLE_BUILD_WITH_CXX.
(meltgc_out_edge): Provide additional flag TDF_DETAILS for dump_edge_info.
(melt_val2passflag): Handle PROP_referenced_vars only when defined.
* melt-module.mk: Use GCCMELT_COMPILER instead of GCCMELT_CC.
* melt-build-script.tpl: Transmit GCCMELT_COMPILER on every make
using melt-module.mk and improve the error message.
* melt-build-script.sh: Regenerate.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@190778 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/sem_eval.adb')
-rw-r--r-- | gcc/ada/sem_eval.adb | 238 |
1 files changed, 131 insertions, 107 deletions
diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb index cecdbef46ab..8553ce62875 100644 --- a/gcc/ada/sem_eval.adb +++ b/gcc/ada/sem_eval.adb @@ -214,6 +214,16 @@ package body Sem_Eval is -- e.g. in the two operand case below, for string comparison, the result -- is not static even though the two operands are static. In such cases, -- the caller must reset the Is_Static_Expression flag in N. + -- + -- If Fold and Stat are both set to False then this routine performs also + -- the following extra actions: + -- + -- If either operand is Any_Type then propagate it to result to + -- prevent cascaded errors. + -- + -- If some operand raises constraint error, then replace the node N + -- with the raise constraint error node. This replacement inherits the + -- Is_Static_Expression flag from the operands. procedure Test_Expression_Is_Foldable (N : Node_Id; @@ -2702,8 +2712,6 @@ package body Sem_Eval is Typ : constant Entity_Id := Etype (Left); Otype : Entity_Id := Empty; Result : Boolean; - Stat : Boolean; - Fold : Boolean; begin -- One special case to deal with first. If we can tell that the result @@ -2919,128 +2927,144 @@ package body Sem_Eval is end Length_Mismatch; end if; - -- Test for expression being foldable - - Test_Expression_Is_Foldable (N, Left, Right, Stat, Fold); - - -- Only comparisons of scalars can give static results. In particular, - -- comparisons of strings never yield a static result, even if both - -- operands are static strings. - - if not Is_Scalar_Type (Typ) then - Stat := False; - Set_Is_Static_Expression (N, False); - end if; + declare + Is_Static_Expression : Boolean; + Is_Foldable : Boolean; + pragma Unreferenced (Is_Foldable); - -- For operators on universal numeric types called as functions with - -- an explicit scope, determine appropriate specific numeric type, and - -- diagnose possible ambiguity. + begin + -- Initialize the value of Is_Static_Expression. The value of + -- Is_Foldable returned by Test_Expression_Is_Foldable is not needed + -- since, even when some operand is a variable, we can still perform + -- the static evaluation of the expression in some cases (for + -- example, for a variable of a subtype of Integer we statically + -- know that any value stored in such variable is smaller than + -- Integer'Last). + + Test_Expression_Is_Foldable + (N, Left, Right, Is_Static_Expression, Is_Foldable); + + -- Only comparisons of scalars can give static results. In + -- particular, comparisons of strings never yield a static + -- result, even if both operands are static strings. + + if not Is_Scalar_Type (Typ) then + Is_Static_Expression := False; + Set_Is_Static_Expression (N, False); + end if; - if Is_Universal_Numeric_Type (Etype (Left)) - and then - Is_Universal_Numeric_Type (Etype (Right)) - then - Otype := Find_Universal_Operator_Type (N); - end if; + -- For operators on universal numeric types called as functions with + -- an explicit scope, determine appropriate specific numeric type, + -- and diagnose possible ambiguity. - -- For static real type expressions, we cannot use Compile_Time_Compare - -- since it worries about run-time results which are not exact. + if Is_Universal_Numeric_Type (Etype (Left)) + and then + Is_Universal_Numeric_Type (Etype (Right)) + then + Otype := Find_Universal_Operator_Type (N); + end if; - if Stat and then Is_Real_Type (Typ) then - declare - Left_Real : constant Ureal := Expr_Value_R (Left); - Right_Real : constant Ureal := Expr_Value_R (Right); + -- For static real type expressions, we cannot use + -- Compile_Time_Compare since it worries about run-time + -- results which are not exact. - begin - case Nkind (N) is - when N_Op_Eq => Result := (Left_Real = Right_Real); - when N_Op_Ne => Result := (Left_Real /= Right_Real); - when N_Op_Lt => Result := (Left_Real < Right_Real); - when N_Op_Le => Result := (Left_Real <= Right_Real); - when N_Op_Gt => Result := (Left_Real > Right_Real); - when N_Op_Ge => Result := (Left_Real >= Right_Real); + if Is_Static_Expression and then Is_Real_Type (Typ) then + declare + Left_Real : constant Ureal := Expr_Value_R (Left); + Right_Real : constant Ureal := Expr_Value_R (Right); - when others => - raise Program_Error; - end case; + begin + case Nkind (N) is + when N_Op_Eq => Result := (Left_Real = Right_Real); + when N_Op_Ne => Result := (Left_Real /= Right_Real); + when N_Op_Lt => Result := (Left_Real < Right_Real); + when N_Op_Le => Result := (Left_Real <= Right_Real); + when N_Op_Gt => Result := (Left_Real > Right_Real); + when N_Op_Ge => Result := (Left_Real >= Right_Real); + + when others => + raise Program_Error; + end case; - Fold_Uint (N, Test (Result), True); - end; + Fold_Uint (N, Test (Result), True); + end; - -- For all other cases, we use Compile_Time_Compare to do the compare + -- For all other cases, we use Compile_Time_Compare to do the compare - else - declare - CR : constant Compare_Result := - Compile_Time_Compare (Left, Right, Assume_Valid => False); + else + declare + CR : constant Compare_Result := + Compile_Time_Compare + (Left, Right, Assume_Valid => False); - begin - if CR = Unknown then - return; - end if; + begin + if CR = Unknown then + return; + end if; - case Nkind (N) is - when N_Op_Eq => - if CR = EQ then - Result := True; - elsif CR = NE or else CR = GT or else CR = LT then - Result := False; - else - return; - end if; + case Nkind (N) is + when N_Op_Eq => + if CR = EQ then + Result := True; + elsif CR = NE or else CR = GT or else CR = LT then + Result := False; + else + return; + end if; - when N_Op_Ne => - if CR = NE or else CR = GT or else CR = LT then - Result := True; - elsif CR = EQ then - Result := False; - else - return; - end if; + when N_Op_Ne => + if CR = NE or else CR = GT or else CR = LT then + Result := True; + elsif CR = EQ then + Result := False; + else + return; + end if; - when N_Op_Lt => - if CR = LT then - Result := True; - elsif CR = EQ or else CR = GT or else CR = GE then - Result := False; - else - return; - end if; + when N_Op_Lt => + if CR = LT then + Result := True; + elsif CR = EQ or else CR = GT or else CR = GE then + Result := False; + else + return; + end if; - when N_Op_Le => - if CR = LT or else CR = EQ or else CR = LE then - Result := True; - elsif CR = GT then - Result := False; - else - return; - end if; + when N_Op_Le => + if CR = LT or else CR = EQ or else CR = LE then + Result := True; + elsif CR = GT then + Result := False; + else + return; + end if; - when N_Op_Gt => - if CR = GT then - Result := True; - elsif CR = EQ or else CR = LT or else CR = LE then - Result := False; - else - return; - end if; + when N_Op_Gt => + if CR = GT then + Result := True; + elsif CR = EQ or else CR = LT or else CR = LE then + Result := False; + else + return; + end if; - when N_Op_Ge => - if CR = GT or else CR = EQ or else CR = GE then - Result := True; - elsif CR = LT then - Result := False; - else - return; - end if; + when N_Op_Ge => + if CR = GT or else CR = EQ or else CR = GE then + Result := True; + elsif CR = LT then + Result := False; + else + return; + end if; - when others => - raise Program_Error; - end case; - end; + when others => + raise Program_Error; + end case; + end; - Fold_Uint (N, Test (Result), Stat); - end if; + Fold_Uint (N, Test (Result), Is_Static_Expression); + end if; + end; -- For the case of a folded relational operator on a specific numeric -- type, freeze operand type now. @@ -4130,7 +4154,7 @@ package body Sem_Eval is -- Never in range if both types are not scalar. Don't know if this can -- actually happen, but just in case. - elsif not Is_Scalar_Type (T1) or else not Is_Scalar_Type (T1) then + elsif not Is_Scalar_Type (T1) or else not Is_Scalar_Type (T2) then return False; -- If T1 has infinities but T2 doesn't have infinities, then T1 is |