From: Ed Schonberg Date: Wed, 26 Sep 2018 09:17:16 +0000 (+0000) Subject: [Ada] Missing predicate check on return value X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=bcbe14db192f03018ea74cf6eb24c04a110ecac0;p=gcc.git [Ada] Missing predicate check on return value The semantics of the return statement includes an implicit conversion of the value to the return type of the funcction. This conversion, as elsewhere, entails a predicate check if the return type has a predicate aspect. We do not apply the check to a case expression because in the context of a return statement it will be expanded into a series of return statements, each of which will receive a predicate check. 2018-09-26 Ed Schonberg gcc/ada/ * sem_ch6.adb (Analyze_Function_Return): If the return type has a dynamic_predicate, apply a Predicate_Check to the expression, given that it is implicitly converted to the return type. Exclude case expressions from the check, because in this context the expression is expanded into individual return statements. gcc/testsuite/ * gnat.dg/predicate3.adb, gnat.dg/predicate3_pkg.ads: New testcase. From-SVN: r264611 --- diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index a0252f8d1af..9db27470fe0 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,11 @@ +2018-09-26 Ed Schonberg + + * sem_ch6.adb (Analyze_Function_Return): If the return type has + a dynamic_predicate, apply a Predicate_Check to the expression, + given that it is implicitly converted to the return type. + Exclude case expressions from the check, because in this context + the expression is expanded into individual return statements. + 2018-09-26 Eric Botcazou * gcc-interface/decl.c (gnat_to_gnu_entity) : In diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index b330426db5c..d0617fe50b9 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -1060,6 +1060,16 @@ package body Sem_Ch6 is Apply_Constraint_Check (Expr, R_Type); + -- The return value is converted to the return type of the function, + -- which implies a predicate check if the return type is predicated. + -- We do not apply the check to a case expression because it will + -- be expanded into a series of return statements, each of which + -- will receive a predicate check. + + if Nkind (Expr) /= N_Case_Expression then + Apply_Predicate_Check (Expr, R_Type); + end if; + -- Ada 2005 (AI-318-02): When the result type is an anonymous access -- type, apply an implicit conversion of the expression to that type -- to force appropriate static and run-time accessibility checks. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c97b9c509ee..3c954322f59 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-09-26 Ed Schonberg + + * gnat.dg/predicate3.adb, gnat.dg/predicate3_pkg.ads: New + testcase. + 2018-09-26 Paolo Carlini PR c++/67656 diff --git a/gcc/testsuite/gnat.dg/predicate3.adb b/gcc/testsuite/gnat.dg/predicate3.adb new file mode 100644 index 00000000000..0d649edcedf --- /dev/null +++ b/gcc/testsuite/gnat.dg/predicate3.adb @@ -0,0 +1,39 @@ +-- { dg-do run } +-- { dg-options "-gnata" } + +with Ada.Assertions, Ada.Text_IO; +use Ada.Assertions, Ada.Text_IO; + +with Predicate3_Pkg; +use Predicate3_Pkg; + +procedure Predicate3 is + Got_Assertion : Boolean := False; +begin + + begin + Put_Line (Good (C)'Image); + exception + when Assertion_Error => + Got_Assertion := True; + end; + + if not Got_Assertion then + raise Program_Error; + end if; + + Got_Assertion := False; + declare + X: Priv; + begin + X := Wrong; + exception + when Assertion_Error => + Got_Assertion := True; + end; + + if not Got_Assertion then + raise Program_Error; + end if; + +end Predicate3; diff --git a/gcc/testsuite/gnat.dg/predicate3_pkg.ads b/gcc/testsuite/gnat.dg/predicate3_pkg.ads new file mode 100644 index 00000000000..a5c2e4cae0e --- /dev/null +++ b/gcc/testsuite/gnat.dg/predicate3_pkg.ads @@ -0,0 +1,22 @@ +package Predicate3_Pkg is + + type Priv is private; + C: constant Priv; + + function Test (X: Priv) return Boolean; + subtype Subt is Priv with Dynamic_Predicate => (Test (Subt)); + + function Wrong return Subt; + function Good (X: Subt) return Boolean; + +private + + type Priv is new Integer; + C: constant Priv := -1; + + function Test (X: Priv) return Boolean is (X > 0); + + function Wrong return Subt is (-1); + function Good (X: Subt) return Boolean is (True); + +end Predicate3_Pkg;