diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index f74e8bb3524..898ae383a01 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2019-09-23 Eric Botcazou + + * gcc-interface/trans.c (gnat_compile_time_expr_list): New variable. + (Pragma_to_gnu): Rename local variable. Save the (first) expression + of pragma Compile_Time_{Error|Warning} for later processing. + (Compilation_Unit_to_gnu): Process the expressions saved above. + 2019-09-23 Eric Botcazou * gcc-interface/trans.c (Attribute_to_gnu): Test Can_Use_Internal_Rep diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 1af477f9924..d9cd84df31f 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -95,6 +95,9 @@ bool type_annotate_only; /* List of N_Validate_Unchecked_Conversion nodes in the unit. */ static vec gnat_validate_uc_list; +/* List of expressions of pragma Compile_Time_{Error|Warning} in the unit. */ +static vec gnat_compile_time_expr_list; + /* When not optimizing, we cache the 'First, 'Last and 'Length attributes of unconstrained array IN parameters to avoid emitting a great deal of redundant instructions to recompute them each time. */ @@ -1508,17 +1511,28 @@ static tree Pragma_to_gnu (Node_Id gnat_node) { tree gnu_result = alloc_stmt_list (); - unsigned char pragma_id; Node_Id gnat_temp; - /* Do nothing if we are just annotating types and check for (and ignore) - unrecognized pragmas. */ - if (type_annotate_only - || !Is_Pragma_Name (Chars (Pragma_Identifier (gnat_node)))) + /* Check for (and ignore) unrecognized pragmas. */ + if (!Is_Pragma_Name (Chars (Pragma_Identifier (gnat_node)))) return gnu_result; - pragma_id = Get_Pragma_Id (Chars (Pragma_Identifier (gnat_node))); - switch (pragma_id) + const unsigned char id + = Get_Pragma_Id (Chars (Pragma_Identifier (gnat_node))); + + /* Save the expression of pragma Compile_Time_{Error|Warning} for later. */ + if (id == Pragma_Compile_Time_Error || id == Pragma_Compile_Time_Warning) + { + gnat_temp = First (Pragma_Argument_Associations (gnat_node)); + gnat_compile_time_expr_list.safe_push (Expression (gnat_temp)); + return gnu_result; + } + + /* Stop there if we are just annotating types. */ + if (type_annotate_only) + return gnu_result; + + switch (id) { case Pragma_Inspection_Point: /* Do nothing at top level: all such variables are already viewable. */ @@ -1670,11 +1684,11 @@ Pragma_to_gnu (Node_Id gnat_node) break; tree gnu_clauses = gnu_loop_stack->last ()->omp_construct_clauses; - if (pragma_id == Pragma_Acc_Data) + if (id == Pragma_Acc_Data) gnu_loop_stack->last ()->omp_code = OACC_DATA; - else if (pragma_id == Pragma_Acc_Kernels) + else if (id == Pragma_Acc_Kernels) gnu_loop_stack->last ()->omp_code = OACC_KERNELS; - else if (pragma_id == Pragma_Acc_Parallel) + else if (id == Pragma_Acc_Parallel) gnu_loop_stack->last ()->omp_code = OACC_PARALLEL; else gcc_unreachable (); @@ -1914,7 +1928,7 @@ Pragma_to_gnu (Node_Id gnat_node) /* This is the String form: pragma Warning{s|_As_Error}(String). */ if (Nkind (Expression (gnat_temp)) == N_String_Literal) { - switch (pragma_id) + switch (id) { case Pragma_Warning_As_Error: kind = DK_ERROR; @@ -6319,7 +6333,7 @@ Compilation_Unit_to_gnu (Node_Id gnat_node) || Nkind (gnat_unit) == N_Subprogram_Body); const Entity_Id gnat_unit_entity = Defining_Entity (gnat_unit); Entity_Id gnat_entity; - Node_Id gnat_pragma; + Node_Id gnat_pragma, gnat_iter; /* Make the decl for the elaboration procedure. Emit debug info for it, so that users can break into their elaboration code in debuggers. Kludge: don't consider it as a definition so that we have a line map for its @@ -6415,6 +6429,12 @@ Compilation_Unit_to_gnu (Node_Id gnat_node) add_stmt_list (Actions (Aux_Decls_Node (gnat_node))); finalize_from_limited_with (); + /* Then process the expressions of pragma Compile_Time_{Error|Warning} to + annotate types referenced therein if they have not been annotated. */ + for (int i = 0; gnat_compile_time_expr_list.iterate (i, &gnat_iter); i++) + (void) gnat_to_gnu_external (gnat_iter); + gnat_compile_time_expr_list.release (); + /* Save away what we've made so far and finish it up. */ set_current_block_context (gnu_elab_proc_decl); gnat_poplevel (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cbf0eff988c..3e64e58274e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-23 Eric Botcazou + + * gnat.dg/specs/compile_time1.ads: New test. + * gnat.dg/specs/compile_time1_pkg.ads! New helper. + 2019-09-22 Marek Polacek PR c++/91819 - ICE with operator++ and enum. diff --git a/gcc/testsuite/gnat.dg/specs/compile_time1.ads b/gcc/testsuite/gnat.dg/specs/compile_time1.ads new file mode 100644 index 00000000000..f28d4e623d7 --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/compile_time1.ads @@ -0,0 +1,9 @@ +-- { dg-do compile } + +with Compile_Time1_Pkg; use Compile_Time1_Pkg; + +package Compile_Time1 is + + pragma Compile_Time_Error (Rec'Size /= Integer'Size, "wrong record size"); + +end Compile_Time1; diff --git a/gcc/testsuite/gnat.dg/specs/compile_time1_pkg.ads b/gcc/testsuite/gnat.dg/specs/compile_time1_pkg.ads new file mode 100644 index 00000000000..c0345c2819e --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/compile_time1_pkg.ads @@ -0,0 +1,7 @@ +package Compile_Time1_Pkg is + + type Rec is record + I : Integer; + end record; + +end Compile_Time1_Pkg;