PIPS
array_bound_check_bottom_up.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "alias_private.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "effects-util.h"
#include "text-util.h"
#include "database.h"
#include "pipsdbm.h"
#include "resources.h"
#include "misc.h"
#include "control.h"
#include "properties.h"
#include "instrumentation.h"
+ Include dependency graph for array_bound_check_bottom_up.c:

Go to the source code of this file.

Data Structures

struct  array_dimension_bound_test
 As we create checks with stop error message who tell us there are bound violations for which array, on which dimension, which bound (lower or upper), the following typedef array_dimension_bound_test permits us to create a sequence of tests for each statement more easier. More...
 
struct  Index_range
 Data structure to support abc Implied DO. More...
 
struct  bottom_up_abc_context_t
 context data structure for bottom_up_abc newgen recursion More...
 
struct  checkfn
 

Macros

#define array_dimension_bound_test_undefined   ((array_dimension_bound_test) {NIL,NIL,NIL,NIL} )
 
#define Index_range_undefined   ((Index_range) {NIL,NIL})
 
#define cf_ge_expression(e1, e2)    ( 1 ? binary_intrinsic_expression(">=", e1, e2) : ge_expression(e1, e2) )
 
#define cf_gt_expression(e1, e2)    ( 1 ? binary_intrinsic_expression(">", e1, e2) : gt_expression(e1, e2) )
 
#define cf_lt_expression(e1, e2)    ( 1 ? binary_intrinsic_expression("<", e1, e2) : lt_expression(e1, e2) )
 
#define cf_and_expression(e1, e2)    ( 1 ? binary_intrinsic_expression("&&", e1, e2) : and_expression(e1, e2) )
 
#define cf_or_expression(e1, e2)    ( 1 ? binary_intrinsic_expression("||", e1, e2) : or_expression(e1, e2) )
 
#define make_add_expression(e1, e2)   make_bin_expression("TOP-LEVEL:+", e1, e2)
 
#define make_sub_expression(e1, e2)   make_bin_expression("TOP-LEVEL:-", e1, e2)
 
#define make_mul_expression(e1, e2)   make_bin_expression("TOP-LEVEL:*", e1, e2)
 
#define CHECK_NARGS(n)   if (nargs != (n)) return expression_undefined
 

Typedefs

typedef struct array_dimension_bound_test array_dimension_bound_test
 As we create checks with stop error message who tell us there are bound violations for which array, on which dimension, which bound (lower or upper), the following typedef array_dimension_bound_test permits us to create a sequence of tests for each statement more easier. More...
 
typedef struct Index_range Index_range
 Data structure to support abc Implied DO. More...
 
typedef struct bottom_up_abc_context_tbottom_up_abc_context_p
 

Functions

static void initialize_bottom_up_abc_statistics ()
 
static void display_bottom_up_abc_statistics ()
 
static bool array_dimension_bound_test_undefined_p (array_dimension_bound_test x)
 
string int_to_dimension (int i)
 Warning! Do not modify this file that is automatically generated! More...
 
bool array_need_bound_check_p (entity e)
 This function returns true, if the array needs bound checks false, otherwise. More...
 
static array_dimension_bound_test make_true_array_dimension_bound_test (entity e, int i, bool low)
 
static array_dimension_bound_test make_array_dimension_bound_test (entity e, int i, bool low, expression exp)
 
static array_dimension_bound_test add_array_dimension_bound_test (array_dimension_bound_test retour, array_dimension_bound_test temp)
 
expression subscript_value (entity arr, list l_inds)
 
static array_dimension_bound_test bottom_up_abc_reference (reference r)
 
static array_dimension_bound_test bottom_up_abc_expression (expression e)
 
static array_dimension_bound_test bottom_up_abc_call (call cal)
 
static array_dimension_bound_test abc_with_allocation_size (reference r)
 The test is: 1 <= offset(e) + subscript_value(r) <= area_size(common) More...
 
static array_dimension_bound_test bottom_up_abc_base_reference_implied_do (reference re, expression ind, range ran)
 
static array_dimension_bound_test bottom_up_abc_reference_implied_do (expression e, Index_range ir)
 
static array_dimension_bound_test bottom_up_abc_expression_implied_do (expression e, Index_range ir)
 
static bool expression_in_array_subscript (expression e, list args)
 
static bool read_statement_with_write_effect_on_array_subscript (call c)
 
string print_variables (expression e)
 
statement emit_message_and_stop (string stop_message)
 
static statement make_bottom_up_abc_tests (array_dimension_bound_test adt)
 
static void bottom_up_abc_insert_before_statement (statement s, statement s1, bottom_up_abc_context_p context)
 
static statement cstr_args_check (statement)
 forward declaration More...
 
static void bottom_up_abc_statement_rwt (statement s, bottom_up_abc_context_p context)
 
static bool store_mapping (control c, bottom_up_abc_context_p context)
 
static bool push_uns (unstructured u, bottom_up_abc_context_p context)
 
static void pop_uns (unstructured u, bottom_up_abc_context_p context)
 
static void bottom_up_abc_statement (statement module_statement)
 
bool array_bound_check_bottom_up (const char *module_name)
 
static expression make_bin_expression (string name, expression e1, expression e2)
 
static expression make_strlen_expression (expression arg)
 
static statement make_c_stop_statement (int abort_program)
 
static int entity_constant_string_size (entity e)
 
static string entity_size_uname (entity e)
 
static expression expression_try_find_size (expression expr)
 
static expression expression_try_find_string_size (expression expr)
 
static expression array_indices_check (expression expr)
 
static expression array_check_add (expression array_expr, expression expr)
 
static expression memcpy_check_expression (expression args[], int nargs)
 
static expression bcopy_check_expression (expression args[], int nargs)
 
static expression bcmp_check_expression (expression args[], int nargs)
 
static expression bzero_check_expression (expression args[], int nargs)
 
static expression memcmp_check_expression (expression args[], int nargs)
 
static expression memmove_check_expression (expression args[], int nargs)
 
static expression memset_check_expression (expression args[], int nargs)
 
static expression strcpy_check_expression (expression args[], int nargs)
 
static expression strncpy_check_expression (expression args[], int nargs)
 
static expression strcat_check_expression (expression args[], int nargs)
 
static expression strncat_check_expression (expression args[], int nargs)
 
static expression sprintf_check_expression (expression args[], int nargs)
 
static expression snprintf_check_expression (expression args[], int nargs)
 
static statement alloc_instrumentation (expression args[], int nargs)
 

Variables

static int number_of_bound_checks
 Statistic variables: More...
 
static int number_of_added_checks
 
static int number_of_bound_violations
 
static struct checkfn checkfns []
 

Macro Definition Documentation

◆ array_dimension_bound_test_undefined

#define array_dimension_bound_test_undefined   ((array_dimension_bound_test) {NIL,NIL,NIL,NIL} )

Definition at line 119 of file array_bound_check_bottom_up.c.

◆ cf_and_expression

#define cf_and_expression (   e1,
  e2 
)     ( 1 ? binary_intrinsic_expression("&&", e1, e2) : and_expression(e1, e2) )

Definition at line 1139 of file array_bound_check_bottom_up.c.

◆ cf_ge_expression

#define cf_ge_expression (   e1,
  e2 
)     ( 1 ? binary_intrinsic_expression(">=", e1, e2) : ge_expression(e1, e2) )

Definition at line 1130 of file array_bound_check_bottom_up.c.

◆ cf_gt_expression

#define cf_gt_expression (   e1,
  e2 
)     ( 1 ? binary_intrinsic_expression(">", e1, e2) : gt_expression(e1, e2) )

Definition at line 1133 of file array_bound_check_bottom_up.c.

◆ cf_lt_expression

#define cf_lt_expression (   e1,
  e2 
)     ( 1 ? binary_intrinsic_expression("<", e1, e2) : lt_expression(e1, e2) )

Definition at line 1136 of file array_bound_check_bottom_up.c.

◆ cf_or_expression

#define cf_or_expression (   e1,
  e2 
)     ( 1 ? binary_intrinsic_expression("||", e1, e2) : or_expression(e1, e2) )

Definition at line 1142 of file array_bound_check_bottom_up.c.

◆ CHECK_NARGS

#define CHECK_NARGS (   n)    if (nargs != (n)) return expression_undefined

Definition at line 1446 of file array_bound_check_bottom_up.c.

◆ Index_range_undefined

#define Index_range_undefined   ((Index_range) {NIL,NIL})

Definition at line 120 of file array_bound_check_bottom_up.c.

◆ make_add_expression

#define make_add_expression (   e1,
  e2 
)    make_bin_expression("TOP-LEVEL:+", e1, e2)

Definition at line 1154 of file array_bound_check_bottom_up.c.

◆ make_mul_expression

#define make_mul_expression (   e1,
  e2 
)    make_bin_expression("TOP-LEVEL:*", e1, e2)

Definition at line 1156 of file array_bound_check_bottom_up.c.

◆ make_sub_expression

#define make_sub_expression (   e1,
  e2 
)    make_bin_expression("TOP-LEVEL:-", e1, e2)

Definition at line 1155 of file array_bound_check_bottom_up.c.

Typedef Documentation

◆ array_dimension_bound_test

As we create checks with stop error message who tell us there are bound violations for which array, on which dimension, which bound (lower or upper), the following typedef array_dimension_bound_test permits us to create a sequence of tests for each statement more easier.


            BOTTOM-UP ARRAY BOUND CHECK VERSION

This program takes as input the current module, adds array range checks (lower and upper bound checks) to every statement that has one or more array accesses. The output is the module with those tests added.

Assumptions : there is no write effect on the array bound expression.

There was a test for write effect on bound here but I put it away (in effect_on_array_bound.c) because it takes time to calculate the effect but in fact this case is rare.

NN 20/03/2002: Attention: tests generated for array whose bounds are modified are not correct See Validation/ArrayBoundCheck/BU_Effect.f

Solution : reput the test effect_on_array_bound, instrument the code with SUBROUTINE EFFECT(A,N) REAL A(N) N_PIPS = N N = 2*N DO I =1,N IF (I. GT. N_PIPS .OR I. LT> 1) STOP A(I) = I ENNDO

Question : other analyses (regions,.. ) are correct ?

Version: change the structure of test: IF (I.LT.lower) THEN STOP "Bound violation ..." IF (I.GT.upper) THEN STOP "Bound violation ..." Add statistics Version : Modify the Implied-DO process

The functions bottom_up_abc_call, bottom_up_abc_reference, bottom_up_abc_expression return results of type array_dimension_bound_test

◆ bottom_up_abc_context_p

◆ Index_range

typedef struct Index_range Index_range

Data structure to support abc Implied DO.

Function Documentation

◆ abc_with_allocation_size()

static array_dimension_bound_test abc_with_allocation_size ( reference  r)
static

The test is: 1 <= offset(e) + subscript_value(r) <= area_size(common)

divided by the element size

divided by the element size

f the ith subscript index is also an array reference, we must check this reference

Definition at line 334 of file array_bound_check_bottom_up.c.

335 {
338  entity e = reference_variable(r);
339  list inds = reference_indices(r);
340  ram ra = storage_ram(entity_storage(e));
341  entity sec = ram_section(ra);
343  int off = ram_offset(ra)/SizeOfElements(b); /* divided by the element size */
344  int size = area_size(type_area(entity_type(sec)))/SizeOfElements(b); /* divided by the element size */
345  int i;
346  expression subval = subscript_value(e,inds);
348  ifdebug(3)
349  {
350  pips_debug(3, "\n Lower bound check expression:");
351  print_expression(check);
352  }
353  clean_all_normalized(check);
354  i = trivial_expression_p(check);
355  switch(i){
356  case 1:
357  {
358  user_log("\n Bound violation on lower bound of array %s\n",entity_local_name(e));
359  return make_true_array_dimension_bound_test(e,0,true);
360  }
361  case -1:
362  break;
363  case 0:
364  {
366  temp = make_array_dimension_bound_test(e,0,true,check);
367  retour = add_array_dimension_bound_test(retour,temp);
368  break;
369  }
370  }
371  check = gt_expression(copy_expression(subval),int_to_expression(size-off));
372  ifdebug(3)
373  {
374  pips_debug(3, "\n Upper bound check expression:");
375  print_expression(check);
376  }
377  clean_all_normalized(check);
378  i = trivial_expression_p(check);
379  switch(i){
380  case 1:
381  {
382  user_log("\n Bound violation on upper bound of array %s\n",entity_local_name(e));
383  return make_true_array_dimension_bound_test(e,0,false);
384  }
385  case -1:
386  break;
387  case 0:
388  {
390  temp = make_array_dimension_bound_test(e,0,false,check);
391  retour = add_array_dimension_bound_test(retour,temp);
392  break;
393  }
394  }
395  /*if the ith subscript index is also an array reference, we must check this reference*/
396  for (i=1;i <= (int) gen_length(inds);i++)
397  {
398  expression ith = find_ith_argument(inds,i);
400  temp = bottom_up_abc_expression(ith);
401  retour = add_array_dimension_bound_test(retour,temp);
402  }
403  return retour;
404 }
void user_log(const char *format,...)
Definition: message.c:234
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
void const char const char const int
expression subscript_value(entity arr, list l_inds)
static array_dimension_bound_test make_array_dimension_bound_test(entity e, int i, bool low, expression exp)
static array_dimension_bound_test make_true_array_dimension_bound_test(entity e, int i, bool low)
static array_dimension_bound_test add_array_dimension_bound_test(array_dimension_bound_test retour, array_dimension_bound_test temp)
static array_dimension_bound_test bottom_up_abc_expression(expression e)
static int number_of_added_checks
static int number_of_bound_checks
Statistic variables:
#define array_dimension_bound_test_undefined
size_t gen_length(const list l)
Definition: list.c:150
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
#define gt_expression(e1, e2)
#define lt_expression(e1, e2)
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
void clean_all_normalized(expression e)
Definition: expression.c:4102
int trivial_expression_p(expression e)
This function returns:
Definition: expression.c:679
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
expression find_ith_argument(list args, int n)
Definition: expression.c:1147
_int SizeOfElements(basic)
This function returns the length in bytes of the Fortran or C type represented by a basic,...
Definition: size.c:297
#define area_size(x)
Definition: ri.h:544
#define reference_variable(x)
Definition: ri.h:2326
#define type_variable(x)
Definition: ri.h:2949
#define entity_storage(x)
Definition: ri.h:2794
#define ram_section(x)
Definition: ri.h:2249
#define reference_indices(x)
Definition: ri.h:2328
#define type_area(x)
Definition: ri.h:2946
#define storage_ram(x)
Definition: ri.h:2521
#define entity_type(x)
Definition: ri.h:2792
#define variable_basic(x)
Definition: ri.h:3120
#define ram_offset(x)
Definition: ri.h:2251
#define ifdebug(n)
Definition: sg.c:47
As we create checks with stop error message who tell us there are bound violations for which array,...
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References add_array_dimension_bound_test(), area_size, array_dimension_bound_test_undefined, bottom_up_abc_expression(), clean_all_normalized(), copy_expression(), entity_local_name(), entity_storage, entity_type, find_ith_argument(), gen_length(), gt_expression, ifdebug, int, int_to_expression(), lt_expression, make_array_dimension_bound_test(), make_true_array_dimension_bound_test(), number_of_added_checks, number_of_bound_checks, pips_debug, print_expression(), ram_offset, ram_section, reference_indices, reference_variable, SizeOfElements(), storage_ram, subscript_value(), trivial_expression_p(), type_area, type_variable, user_log(), and variable_basic.

Referenced by bottom_up_abc_reference().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_array_dimension_bound_test()

static array_dimension_bound_test add_array_dimension_bound_test ( array_dimension_bound_test  retour,
array_dimension_bound_test  temp 
)
static

If in temp.exp, there are expressions that exist in retour.exp, we don't have to add those expressions to retour.exp If temp.exp is a true expression => add to list to debug several real bound violations

Definition at line 232 of file array_bound_check_bottom_up.c.

234 {
236  {
238  {
239  pips_debug(3, "\n Add bound checks for array: %s",entity_local_name(ENTITY(CAR(temp.arr))));
240  return temp;
241  }
242  /* If in temp.exp, there are expressions that exist
243  in retour.exp, we don't have to add those expressions to retour.exp
244  If temp.exp is a true expression => add to list to debug several real bound violations*/
245  while (!ENDP(temp.exp))
246  {
247  expression exp = EXPRESSION(CAR(temp.exp));
248  pips_debug(3, "\n Add bound checks for array: %s",entity_local_name(ENTITY(CAR(temp.arr))));
250  {
251  retour.arr = gen_nconc(CONS(ENTITY,ENTITY(CAR(temp.arr)),NIL),retour.arr);
252  retour.dim = gen_nconc(CONS(INT,INT(CAR(temp.dim)),NIL),retour.dim);
253  retour.bou = gen_nconc(CONS(BOOL,BOOL(CAR(temp.bou)),NIL),retour.bou);
254  retour.exp = gen_nconc(CONS(EXPRESSION,exp,NIL),retour.exp);
255  }
256  else
258  temp.arr = CDR(temp.arr);
259  temp.dim = CDR(temp.dim);
260  temp.bou = CDR(temp.bou);
261  temp.exp = CDR(temp.exp);
262  }
263  }
264  return retour;
265 }
static bool array_dimension_bound_test_undefined_p(array_dimension_bound_test x)
@ INT
Definition: atomic.c:48
#define BOOL(x)
Definition: genC.h:83
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
bool same_expression_in_list_p(expression e, list le)
This function returns true, if there exists a same expression in the list false, otherwise.
Definition: expression.c:557
bool true_expression_p(expression e)
Definition: expression.c:1113
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207

References array_dimension_bound_test::arr, array_dimension_bound_test_undefined_p(), BOOL, array_dimension_bound_test::bou, CAR, CDR, CONS, array_dimension_bound_test::dim, ENDP, ENTITY, entity_local_name(), exp, array_dimension_bound_test::exp, EXPRESSION, gen_nconc(), INT, NIL, number_of_added_checks, pips_debug, same_expression_in_list_p(), and true_expression_p().

Referenced by abc_with_allocation_size(), bottom_up_abc_base_reference_implied_do(), bottom_up_abc_call(), bottom_up_abc_expression_implied_do(), bottom_up_abc_reference(), and bottom_up_abc_reference_implied_do().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ alloc_instrumentation()

static statement alloc_instrumentation ( expression  args[],
int  nargs 
)
static

Definition at line 1737 of file array_bound_check_bottom_up.c.

1738 {
1739  expression size_expr, size_holder;
1740  entity ptr, size_holder_ent;
1741  string func_name, size_holder_name;
1742  call func_call;
1743  list func_args;
1744  reference ref;
1745  int func_nargs;
1746 
1747  if (nargs != 2) {
1748  return statement_undefined;
1749  }
1750 
1751  if (!expression_reference_p(args[0]) || !expression_call_p(args[1]))
1752  return statement_undefined;
1753 
1755  ptr = reference_variable(ref);
1756 
1757  /*
1758  * Don't try to instrument if the pointer is an array access.
1759  */
1760  if (reference_indices(ref) != NIL)
1761  return statement_undefined;
1762 
1763  func_call = syntax_call(expression_syntax(args[1]));
1764  func_name = entity_name(call_function(func_call));
1765  func_args = call_arguments(func_call);
1766  func_nargs = gen_length(func_args);
1767 
1768  if (strcmp(func_name, "TOP-LEVEL:malloc") == 0) {
1769  if (func_nargs != 1)
1770  return statement_undefined;
1771  size_expr = EXPRESSION(CAR(func_args));
1772  } else if (strcmp(func_name, "TOP-LEVEL:realloc") == 0
1773  || strcmp(func_name, "TOP-LEVEL:memalign") == 0) {
1774  if (func_nargs != 2)
1775  return statement_undefined;
1776  size_expr = EXPRESSION(CAR(CDR(func_args)));
1777  } else if (strcmp(func_name, "TOP-LEVEL:calloc") == 0) {
1778  if (func_nargs != 2)
1779  return statement_undefined;
1781  func_args);
1782  } else
1783  return statement_undefined;
1784 
1785  /*
1786  * Create a new variable to hold the size of the allocated
1787  * memory.
1788  */
1789  size_holder_name = entity_size_uname(ptr);
1790  size_holder_ent = FindEntity("main",
1791  size_holder_name);
1792  if (size_holder_ent == entity_undefined) {
1793  size_holder_ent =
1794  make_scalar_entity(size_holder_name,
1795  // XXX ?? marche pas ...
1796  //STATIC_AREA_LOCAL_NAME, make_basic_int(4));
1797  "main", make_basic_int(4));
1798  }
1799  size_holder = make_entity_expression(size_holder_ent, NIL);
1800 
1801  return make_assign_statement(size_holder, size_expr);
1802 }
basic make_basic_int(intptr_t _field_)
Definition: ri.c:158
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
static string entity_size_uname(entity e)
statement make_assign_statement(expression, expression)
Definition: statement.c:583
#define MULTIPLY_OPERATOR_NAME
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression make_entity_expression(entity e, cons *inds)
Definition: expression.c:176
bool expression_call_p(expression e)
Definition: expression.c:415
expression make_call_expression(entity e, list l)
Build an expression that call an function entity with an argument list.
Definition: expression.c:321
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
entity make_scalar_entity(const char *, const char *, basic)
entity make_scalar_entity(name, module_name, base)
Definition: variable.c:331
#define syntax_reference(x)
Definition: ri.h:2730
#define call_function(x)
Definition: ri.h:709
#define entity_undefined
Definition: ri.h:2761
#define entity_name(x)
Definition: ri.h:2790
#define syntax_call(x)
Definition: ri.h:2736
#define call_arguments(x)
Definition: ri.h:711
#define expression_syntax(x)
Definition: ri.h:1247
#define statement_undefined
Definition: ri.h:2419

References call_arguments, call_function, CAR, CDR, entity_intrinsic(), entity_name, entity_size_uname(), entity_undefined, EXPRESSION, expression_call_p(), expression_reference_p(), expression_syntax, FindEntity(), gen_length(), make_assign_statement(), make_basic_int(), make_call_expression(), make_entity_expression(), make_scalar_entity(), MULTIPLY_OPERATOR_NAME, NIL, ref, reference_indices, reference_variable, statement_undefined, syntax_call, and syntax_reference.

Referenced by cstr_args_check().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ array_bound_check_bottom_up()

bool array_bound_check_bottom_up ( const char *  module_name)

Begin the dynamic array bound checking phase. Get the code from dbm (true resource)

Reorder the module, because the bound checks have been added

Parameters
module_nameodule_name

Definition at line 1093 of file array_bound_check_bottom_up.c.

1094 {
1097  /* Begin the dynamic array bound checking phase.
1098  * Get the code from dbm (true resource) */
1102  debug_on("ARRAY_BOUND_CHECK_BOTTOM_UP_DEBUG_LEVEL");
1103  ifdebug(1)
1104  {
1105  debug(1, "Array bound check","Begin for %s\n", module_name);
1106  pips_assert("Statement is consistent ...", statement_consistent_p(module_statement));
1107  }
1111  /* Reorder the module, because the bound checks have been added */
1113  ifdebug(1)
1114  {
1115  pips_assert("Statement is consistent ...", statement_consistent_p(module_statement));
1116  debug(1, "array bound check","End for %s\n", module_name);
1117  }
1118  debug_off();
1123  return true;
1124 }
bool statement_consistent_p(statement p)
Definition: ri.c:2195
static statement module_statement
Definition: alias_check.c:125
static void initialize_bottom_up_abc_statistics()
static void display_bottom_up_abc_statistics()
static void bottom_up_abc_statement(statement module_statement)
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
#define debug_on(env)
Definition: misc-local.h:157
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define debug_off()
Definition: misc-local.h:160
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
hash_table set_ordering_to_statement(statement s)
To be used instead of initialize_ordering_to_statement() to make sure that the hash table ots is in s...
Definition: ordering.c:172
void reset_ordering_to_statement(void)
Reset the mapping from ordering to statement.
Definition: ordering.c:185
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450

References bottom_up_abc_statement(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug(), debug_off, debug_on, display_bottom_up_abc_statistics(), ifdebug, initialize_bottom_up_abc_statistics(), local_name_to_top_level_entity(), module_name(), module_reorder(), module_statement, pips_assert, reset_current_module_entity(), reset_current_module_statement(), reset_ordering_to_statement(), set_current_module_entity(), set_current_module_statement(), set_ordering_to_statement(), and statement_consistent_p().

+ Here is the call graph for this function:

◆ array_check_add()

static expression array_check_add ( expression  array_expr,
expression  expr 
)
static

Definition at line 1436 of file array_bound_check_bottom_up.c.

1437 {
1438  expression check;
1439 
1440  if ((check = array_indices_check(array_expr)) == expression_undefined)
1441  return expr;
1442  else
1443  return cf_and_expression(check, expr);
1444 }
#define cf_and_expression(e1, e2)
static expression array_indices_check(expression expr)
#define expression_undefined
Definition: ri.h:1223

References array_indices_check(), cf_and_expression, and expression_undefined.

Referenced by cstr_args_check().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ array_dimension_bound_test_undefined_p()

static bool array_dimension_bound_test_undefined_p ( array_dimension_bound_test  x)
static

Definition at line 155 of file array_bound_check_bottom_up.c.

156 {
157  if ((x.arr == NIL) && (x.dim == NIL) && (x.bou == NIL) && (x.exp == NIL))
158  return true;
159  return false;
160 }
static char * x
Definition: split_file.c:159

References NIL, and x.

Referenced by add_array_dimension_bound_test(), and bottom_up_abc_statement_rwt().

+ Here is the caller graph for this function:

◆ array_indices_check()

static expression array_indices_check ( expression  expr)
static

Definition at line 1377 of file array_bound_check_bottom_up.c.

1378 {
1379  reference ref;
1380  entity e;
1381  variable var;
1382  list dims, acc;
1383  expression check = expression_undefined, checktmp, indice;
1384 
1385  if (!expression_reference_p(expr))
1386  return expression_undefined;
1387  else {
1389  e = reference_variable(ref);
1390  if (!type_variable_p(entity_type(e)))
1391  return expression_undefined;
1392  }
1393  var = type_variable(entity_type(e));
1394  dims = variable_dimensions(var);
1395  acc = reference_indices(ref);
1396 
1397  while (1) {
1398  if (!ENDP(acc) && !ENDP(dims)) {
1399  /*
1400  * We found the upper bound of the given
1401  * expression, we need to add one to get the
1402  * size of the buffer
1403  */
1404  expression upper_bound =
1405  dimension_upper(DIMENSION(CAR(dims)));
1406 
1407  if (expression_constant_p(upper_bound)) {
1408  upper_bound = int_to_expression(1
1409  + expression_to_int(upper_bound));
1410  } else
1411  upper_bound = make_add_expression(upper_bound,
1412  int_to_expression(1));
1413 
1414  /*
1415  * Create the check for the current dimension (checktmp):
1416  * indice < upper_bound
1417  * Add it to the global check:
1418  * check := check && checktmp
1419  */
1420  indice = EXPRESSION(CAR(acc));
1421  checktmp = cf_lt_expression(indice, upper_bound);
1422  if (check == expression_undefined)
1423  check = checktmp;
1424  else
1425  check = cf_and_expression(check, checktmp);
1426 
1427  acc = CDR(acc);
1428  dims = CDR(dims);
1429  } else
1430  break;
1431  }
1432  return check;
1433 }
#define cf_lt_expression(e1, e2)
#define make_add_expression(e1, e2)
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
int expression_to_int(expression exp)
================================================================
Definition: expression.c:2205
#define dimension_upper(x)
Definition: ri.h:982
#define variable_dimensions(x)
Definition: ri.h:3122
#define type_variable_p(x)
Definition: ri.h:2947

References CAR, CDR, cf_and_expression, cf_lt_expression, DIMENSION, dimension_upper, ENDP, entity_type, EXPRESSION, expression_constant_p(), expression_reference_p(), expression_syntax, expression_to_int(), expression_undefined, int_to_expression(), make_add_expression, ref, reference_indices, reference_variable, syntax_reference, type_variable, type_variable_p, and variable_dimensions.

Referenced by array_check_add().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ array_need_bound_check_p()

bool array_need_bound_check_p ( entity  e)

This function returns true, if the array needs bound checks false, otherwise.

If the arrays are not created by user, for example the arrays of Logical Units : LUNS, END_LUNS, ERR_LUNS, ... in the IO_EFFECTS_PACKAGE_NAME, we don't have to check array references for those arrays. Maybe we have to add other kinds of arrays, not only those in IO_EFFECTS

Definition at line 196 of file array_bound_check_bottom_up.c.

197 {
198  const char* s = entity_module_name(e);
199  if (strcmp(s,IO_EFFECTS_PACKAGE_NAME)==0)
200  return false;
201  return true;
202 }
#define IO_EFFECTS_PACKAGE_NAME
Implicit variables to handle IO effetcs.
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092

References entity_module_name(), and IO_EFFECTS_PACKAGE_NAME.

Referenced by bottom_up_abc_reference(), bottom_up_abc_reference_implied_do(), initial_code_abc_reference(), and top_down_abc_flt().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ bcmp_check_expression()

static expression bcmp_check_expression ( expression  args[],
int  nargs 
)
static

Definition at line 1489 of file array_bound_check_bottom_up.c.

1490 {
1491  CHECK_NARGS(3);
1492  return memcpy_check_expression(args, nargs);
1493 }
static expression memcpy_check_expression(expression args[], int nargs)
#define CHECK_NARGS(n)

References CHECK_NARGS, and memcpy_check_expression().

+ Here is the call graph for this function:

◆ bcopy_check_expression()

static expression bcopy_check_expression ( expression  args[],
int  nargs 
)
static

Definition at line 1476 of file array_bound_check_bottom_up.c.

1477 {
1478  CHECK_NARGS(3);
1479  // The arguments order (for the two first) doesn't matter
1480  return memcpy_check_expression(args, nargs);
1481 }

References CHECK_NARGS, and memcpy_check_expression().

Referenced by memmove_check_expression().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ bottom_up_abc_base_reference_implied_do()

static array_dimension_bound_test bottom_up_abc_base_reference_implied_do ( reference  re,
expression  ind,
range  ran 
)
static

Definition at line 507 of file array_bound_check_bottom_up.c.

510 {
512  entity ent = reference_variable(re);
513  list arrayinds = reference_indices(re);
515  expression low = range_lower(ran);
516  expression up = range_upper(ran);
518  int i;
519  for (i=1;i <= (int) gen_length(arrayinds);i++)
520  {
522  ith = find_ith_argument(arrayinds,i);
523  if (expression_equal_p(ith,ind))
524  {
525  int k;
526  dimension dimi = find_ith_dimension(listdims,i);
529  // make expression e1.LT.lower
530  check = lt_expression(low,dimension_lower(copy_dimension(dimi)));
531  ifdebug(3)
532  {
533  pips_debug(3,"\n Lower bound check expression:");
534  print_expression(check);
535  }
536  clean_all_normalized(check);
537  k = trivial_expression_p(check);
538  switch(k){
539  case 1:
540  {
541  user_log("\n Bound violation on lower bound of array %s\n",entity_local_name(ent));
542  return make_true_array_dimension_bound_test(ent,i,true);
543  }
544  case -1:
545  break;
546  case 0:
547  {
549  temp = make_array_dimension_bound_test(ent,i,true,check);
550  retour = add_array_dimension_bound_test(retour,temp);
551  break;
552  }
553  }
554  if (!unbounded_dimension_p(dimi))
555  {
556  check = gt_expression(up,dimension_upper(copy_dimension(dimi)));
557  ifdebug(3)
558  {
559  pips_debug(3, "Upper bound check expression:");
560  print_expression(check);
561  }
562  clean_all_normalized(check);
563  k = trivial_expression_p(check);
564  switch(k){
565  case 1:
566  {
567  user_log("\n Bound violation on upper bound of array %s\n",entity_local_name(ent));
568  return make_true_array_dimension_bound_test(ent,i,false);
569  }
570  case -1:
571  break;
572  case 0:
573  {
575  temp = make_array_dimension_bound_test(ent,i,false,check);
576  retour = add_array_dimension_bound_test(retour,temp);
577  break;
578  }
579  }
580  }
581  }
582  }
583  return retour;
584 }
dimension copy_dimension(dimension p)
DIMENSION.
Definition: ri.c:529
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347
bool unbounded_dimension_p(dimension dim)
bool unbounded_dimension_p(dim) input : a dimension of an array entity.
Definition: expression.c:1130
dimension find_ith_dimension(list, int)
This function returns the ith dimension of a list of dimensions.
Definition: type.c:5621
#define range_upper(x)
Definition: ri.h:2290
#define dimension_lower(x)
Definition: ri.h:980
#define range_lower(x)
Definition: ri.h:2288

References add_array_dimension_bound_test(), array_dimension_bound_test_undefined, clean_all_normalized(), copy_dimension(), dimension_lower, dimension_upper, entity_local_name(), entity_type, expression_equal_p(), expression_undefined, find_ith_argument(), find_ith_dimension(), gen_length(), gt_expression, ifdebug, int, lt_expression, make_array_dimension_bound_test(), make_true_array_dimension_bound_test(), number_of_added_checks, number_of_bound_checks, pips_debug, print_expression(), range_lower, range_upper, reference_indices, reference_variable, trivial_expression_p(), type_variable, unbounded_dimension_p(), user_log(), and variable_dimensions.

Referenced by bottom_up_abc_reference_implied_do().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ bottom_up_abc_call()

static array_dimension_bound_test bottom_up_abc_call ( call  cal)
static

We must check a special case: The call is a READ statement with array reference whose index is read in the same statement.

Example : READ *,N, A(N) or READ *,N,(A(I),I=1,N) (implied DO expression)

In these case, we have to put a dynamic check function such as : READ *,N,(A(abc_check(I,1,10)),I=1,N),M where abc_check is a function that does the range checking by using its parameters

Definition at line 779 of file array_bound_check_bottom_up.c.

780 {
781  list args = call_arguments(cal);
783  /* We must check a special case:
784  * The call is a READ statement with array reference whose index is
785  * read in the same statement.
786  *
787  * Example : READ *,N, A(N) or READ *,N,(A(I),I=1,N) (implied DO expression)
788  *
789  * In these case, we have to put a dynamic check function such as :
790  * READ *,N,(A(abc_check(I,1,10)),I=1,N),M
791  * where abc_check is a function that does the range checking by using its parameters */
792 
794  user_log("\n Warning : READ statement with write effect on array subscript. \n This case has not been treated yet :-( \n");
795  else
796  MAP(EXPRESSION, e,
797  {
799  retour = add_array_dimension_bound_test(retour,temp);
800  },args);
801  return retour;
802 }
static bool read_statement_with_write_effect_on_array_subscript(call c)
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226

References add_array_dimension_bound_test(), array_dimension_bound_test_undefined, bottom_up_abc_expression(), call_arguments, EXPRESSION, MAP, read_statement_with_write_effect_on_array_subscript(), and user_log().

Referenced by bottom_up_abc_expression(), and bottom_up_abc_statement_rwt().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ bottom_up_abc_expression()

static array_dimension_bound_test bottom_up_abc_expression ( expression  e)
static

the syntax of an expression can be a reference, a range or a call

There is nothing to check here

Definition at line 685 of file array_bound_check_bottom_up.c.

686 {
687  /* the syntax of an expression can be a reference, a range or a call*/
691  else
692  {
693  syntax s = expression_syntax(e);
694  tag t = syntax_tag(s);
695  switch (t){
696  case is_syntax_call:
697  {
698  retour = bottom_up_abc_call(syntax_call(s));
699  break;
700  }
701  case is_syntax_reference:
702  {
704  break;
705  }
706  case is_syntax_range:
707  /* There is nothing to check here*/
708  break;
709  }
710  }
711  return retour;
712 }
#define Index_range_undefined
static array_dimension_bound_test bottom_up_abc_expression_implied_do(expression e, Index_range ir)
static array_dimension_bound_test bottom_up_abc_reference(reference r)
static array_dimension_bound_test bottom_up_abc_call(call cal)
int tag
TAG.
Definition: newgen_types.h:92
bool expression_implied_do_p(e)
Definition: expression.c:817
#define syntax_tag(x)
Definition: ri.h:2727
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_reference
Definition: ri.h:2691

References array_dimension_bound_test_undefined, bottom_up_abc_call(), bottom_up_abc_expression_implied_do(), bottom_up_abc_reference(), expression_implied_do_p(), expression_syntax, Index_range_undefined, is_syntax_call, is_syntax_range, is_syntax_reference, syntax_call, syntax_reference, and syntax_tag.

Referenced by abc_with_allocation_size(), bottom_up_abc_call(), bottom_up_abc_reference(), and bottom_up_abc_statement_rwt().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ bottom_up_abc_expression_implied_do()

static array_dimension_bound_test bottom_up_abc_expression_implied_do ( expression  e,
Index_range  ir 
)
static

An implied-DO is a call to an intrinsic function named IMPLIED-DO; the first argument is the implied-DO variable (loop index) the second one is a range the remaining arguments are expressions to be written or references to be read or another implied-DO (dlist, i=e1,e2,e3)

We treated only the case where e3=1 (or omitted), the bound tests is IF (e1.LT.lower.OR.e2.GT.upper) STOP Bound violation for statement READ *,(A(I),I=e1,e2)

An Implied-DO can be occurred in a DATA statement or an input/output statement. As DATA statement is in the declaration, not executable, we do not need to pay attention to it.

range e1,e2,e3

The increment is 1

Implied-DO index

normal expression

increment <> 1, we have to put a dynamic test function such as : WRITE *, A(checkA(I), e1,e2,e3) where checkA is a function that does the range checking for array A. because it is not integer, the bound tests :

if (e3.GT.0).AND.(e1.LT.lower.OR.e1+e3x[e2-e1/e3].GT.upper) STOP Bound violation if (e3.LT.0).AND.(e1.GT.upper.OR.e1+e3x[e1-e2/e3].LT.lower) STOP Bound violation

Definition at line 630 of file array_bound_check_bottom_up.c.

631 {
632  /* An implied-DO is a call to an intrinsic function named IMPLIED-DO;
633  * the first argument is the implied-DO variable (loop index)
634  * the second one is a range
635  * the remaining arguments are expressions to be written or references
636  * to be read or another implied-DO
637  * (dlist, i=e1,e2,e3)
638  *
639  * We treated only the case where e3=1 (or omitted), the bound tests is
640  * IF (e1.LT.lower.OR.e2.GT.upper) STOP Bound violation
641  * for statement READ *,(A(I),I=e1,e2)
642  *
643  * An Implied-DO can be occurred in a DATA statement or an input/output
644  * statement. As DATA statement is in the declaration, not executable,
645  * we do not need to pay attention to it.*/
648  expression arg2 = EXPRESSION(CAR(CDR(args))); /* range e1,e2,e3*/
650  expression one_exp = int_to_expression(1);
651  if (same_expression_p(range_increment(r),one_exp))
652  {
653  /* The increment is 1 */
654  expression arg1 = EXPRESSION(CAR(args)); /* Implied-DO index*/
655  args = CDR(CDR(args));
656  MAP(EXPRESSION, expr,
657  {
659  Index_range new_ir;
660  new_ir.ind = gen_nconc(CONS(EXPRESSION,arg1,NIL),ir.ind);
661  new_ir.ran = gen_nconc(CONS(RANGE,r,NIL),ir.ran);
662  if (expression_implied_do_p(expr))
663  temp = bottom_up_abc_expression_implied_do(expr,new_ir);
664  else
665  /* normal expression */
666  temp = bottom_up_abc_reference_implied_do(expr,new_ir);
667  retour = add_array_dimension_bound_test(retour,temp);
668  },args);
669  }
670  else
671  {
672  /* increment <> 1, we have to put a dynamic test function such as :
673  * WRITE *, A(checkA(I), e1,e2,e3)
674  * where checkA is a function that does the range checking for array A.
675  * because it is not integer, the bound tests :
676  *
677  * if (e3.GT.0).AND.(e1.LT.lower.OR.e1+e3x[e2-e1/e3].GT.upper)
678  * STOP Bound violation
679  * if (e3.LT.0).AND.(e1.GT.upper.OR.e1+e3x[e1-e2/e3].LT.lower)
680  * STOP Bound violation */
681  }
682  return retour;
683 }
static array_dimension_bound_test bottom_up_abc_reference_implied_do(expression e, Index_range ir)
bool same_expression_p(expression e1, expression e2)
this is slightly different from expression_equal_p, as it will return true for a+b vs b+a
Definition: expression.c:1426
#define syntax_range(x)
Definition: ri.h:2733
#define range_increment(x)
Definition: ri.h:2292
#define RANGE(x)
RANGE.
Definition: ri.h:2257
Data structure to support abc Implied DO.

References add_array_dimension_bound_test(), array_dimension_bound_test_undefined, bottom_up_abc_reference_implied_do(), call_arguments, CAR, CDR, CONS, EXPRESSION, expression_implied_do_p(), expression_syntax, gen_nconc(), Index_range::ind, int_to_expression(), MAP, NIL, Index_range::ran, RANGE, range_increment, same_expression_p(), syntax_call, and syntax_range.

Referenced by bottom_up_abc_expression().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ bottom_up_abc_insert_before_statement()

static void bottom_up_abc_insert_before_statement ( statement  s,
statement  s1,
bottom_up_abc_context_p  context 
)
static

If s is in an unstructured instruction, we must pay attention when inserting s1 before s.

take the control that has s as its statement

take the unstructured correspond to the control c

for a consistent unstructured, a test must have 2 successors, so if s1 is a test, we transform it into sequence in order to avoid this constraint. Then we create a new control for it, with the predecessors are those of c and the only one successor is c. The new predecessors of c are only the new control

if c is the entry node of the correspond unstructured u, the newc will become the new entry node of u

Definition at line 918 of file array_bound_check_bottom_up.c.

920 {
921  /* If s is in an unstructured instruction, we must pay attention
922  when inserting s1 before s. */
924  {
925  /* take the control that has s as its statement */
927  if (stack_size(context->uns)>0)
928  {
929  /* take the unstructured correspond to the control c */
931  control newc;
932  ifdebug(5)
933  {
934  pips_debug(5,"Unstructured case: \n");
935  print_statement(s);
936  }
937  /* for a consistent unstructured, a test must have 2 successors,
938  so if s1 is a test, we transform it into sequence in order
939  to avoid this constraint.
940  Then we create a new control for it, with the predecessors
941  are those of c and the only one successor is c.
942  The new predecessors of c are only the new control*/
943  if (statement_test_p(s1))
944  {
945  list seq = CONS(STATEMENT,s1,NIL);
947  make_sequence(seq)));
948  ifdebug(5)
949  {
950  pips_debug(5, "Unstructured case, insert a test:\n");
952  print_statement(s2);
953  }
954  newc = make_control(s2, control_predecessors(c), CONS(CONTROL, c, NIL));
955  }
956  else
958  // replace c by newc as successor of each predecessor of c
959  MAP(CONTROL, co,
960  {
961  MAPL(lc,
962  {
963  if (CONTROL(CAR(lc))==c) CONTROL_(CAR(lc)) = newc;
964  }, control_successors(co));
965  },control_predecessors(c));
967  /* if c is the entry node of the correspond unstructured u,
968  the newc will become the new entry node of u */
969  if (unstructured_entry(u)==c)
970  unstructured_entry(u) = newc;
971  }
972  else
973  // there is no unstructured (?)
974  insert_statement(s,s1,true);
975  }
976  else
977  // structured case
978  insert_statement(s,s1,true);
979 }
control apply_persistant_statement_to_control(persistant_statement_to_control f, statement k)
Definition: ri.c:1597
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
bool bound_persistant_statement_to_control_p(persistant_statement_to_control f, statement k)
Definition: ri.c:1609
sequence make_sequence(list a)
Definition: ri.c:2125
control make_control(statement a1, list a2, list a3)
Definition: ri.c:523
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
bool statement_test_p(statement)
Definition: statement.c:343
void insert_statement(statement, statement, bool)
This is the normal entry point.
Definition: statement.c:2570
void * stack_head(const stack)
returns the item on top of stack s
Definition: stack.c:420
int stack_size(const stack)
observers
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
#define CONTROL_(x)
Definition: ri.h:913
#define control_predecessors(x)
Definition: ri.h:943
struct _newgen_struct_unstructured_ * unstructured
Definition: ri.h:447
#define CONTROL(x)
CONTROL.
Definition: ri.h:910
@ is_instruction_sequence
Definition: ri.h:1469
#define control_successors(x)
Definition: ri.h:945
#define unstructured_entry(x)
Definition: ri.h:3004
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
s1
Definition: set.c:247
Definition: delay.c:253

References apply_persistant_statement_to_control(), bound_persistant_statement_to_control_p(), CAR, CONS, CONTROL, CONTROL_, control_predecessors, control_successors, ifdebug, insert_statement(), instruction_to_statement(), is_instruction_sequence, make_control(), make_instruction(), make_sequence(), MAP, MAPL, NIL, pips_debug, print_statement(), s1, stack_head(), stack_size(), STATEMENT, statement_test_p(), and unstructured_entry.

Referenced by bottom_up_abc_statement_rwt().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ bottom_up_abc_reference()

static array_dimension_bound_test bottom_up_abc_reference ( reference  r)
static

In practice, bound violations often occur with arrays in a common, with the reason that the allocated size of the common is not violated :-))) So this property helps dealing with this kind of bad programming practice

Call the function trivial_expression_p(check)

  • If the check expression is always TRUE: there is certainly bound violation, we return retour immediately: retour = ({e},{i},{bound},{.TRUE.})
  • If the check expression is always false, we don't have to add check to retour.
  • Otherwise, we have to add check to retour.

If the dimension is unbounded , for example T(*), we cannot check the upper bound

f the ith subscript index is also an array reference, we must check this reference

Definition at line 407 of file array_bound_check_bottom_up.c.

408 {
410  ifdebug(3)
411  {
412  pips_debug(3, "\n Array bound check for reference:");
413  print_reference(r);
414  }
415  if (array_reference_p(r))
416  {
417  entity e = reference_variable(r);
419  {
420  /* In practice, bound violations often occur with arrays in a common, with the reason that
421  the allocated size of the common is not violated :-)))
422  So this property helps dealing with this kind of bad programming practice*/
423  if (variable_in_common_p(e) && get_bool_property("ARRAY_BOUND_CHECKING_WITH_ALLOCATION_SIZE"))
424  retour = abc_with_allocation_size(r);
425  else
426  {
428  list arrayinds = reference_indices(r);
430  expression ith, check = expression_undefined;
431  int i,k;
433  for (i=1;i <= (int) gen_length(arrayinds);i++)
434  {
436  dimi = find_ith_dimension(arraydims,i);
437  ith = find_ith_argument(arrayinds,i);
439  /* Call the function trivial_expression_p(check)
440  * + If the check expression is always TRUE:
441  * there is certainly bound violation, we return retour
442  * immediately: retour = ({e},{i},{bound},{.TRUE.})
443  * + If the check expression is always false, we don't have to add check to retour.
444  * + Otherwise, we have to add check to retour.*/
445  ifdebug(3)
446  {
447  pips_debug(3, "\n Lower bound check expression:");
448  print_expression(check);
449  }
450  clean_all_normalized(check);
451  k = trivial_expression_p(check);
452  switch(k){
453  case 1:
454  {
455  user_log("\n Bound violation on lower bound of array %s\n",entity_local_name(e));
456  return make_true_array_dimension_bound_test(e,i,true);
457  }
458  case -1:
459  break;
460  case 0:
461  {
463  temp = make_array_dimension_bound_test(e,i,true,check);
464  retour = add_array_dimension_bound_test(retour,temp);
465  break;
466  }
467  }
468  /* If the dimension is unbounded , for example T(*), we cannot check the upper bound*/
469  if (!unbounded_dimension_p(dimi))
470  {
472  ifdebug(3)
473  {
474  pips_debug(3, "\n Upper bound check expression:");
475  print_expression(check);
476  }
477  clean_all_normalized(check);
478  k = trivial_expression_p(check);
479  switch(k){
480  case 1:
481  {
482  user_log("\n Bound violation on upper bound of array %s\n",entity_local_name(e));
483  return make_true_array_dimension_bound_test(e,i,false);
484  }
485  case -1:
486  break;
487  case 0:
488  {
490  temp = make_array_dimension_bound_test(e,i,false,check);
491  retour = add_array_dimension_bound_test(retour,temp);
492  break;
493  }
494  }
495  }
496  /*if the ith subscript index is also an array reference, we must check this reference*/
497  temp = bottom_up_abc_expression(ith);
498  retour = add_array_dimension_bound_test(retour,temp);
499  }
500  }
501  }
502  }
503  return retour;
504 }
static array_dimension_bound_test abc_with_allocation_size(reference r)
The test is: 1 <= offset(e) + subscript_value(r) <= area_size(common)
bool array_need_bound_check_p(entity e)
This function returns true, if the array needs bound checks false, otherwise.
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
void print_reference(reference r)
Definition: expression.c:142
bool array_reference_p(reference r)
predicates on references
Definition: expression.c:1861
bool variable_in_common_p(entity)
true if v is in a common.
Definition: variable.c:1570
#define dimension_undefined
Definition: ri.h:955

References abc_with_allocation_size(), add_array_dimension_bound_test(), array_dimension_bound_test_undefined, array_need_bound_check_p(), array_reference_p(), bottom_up_abc_expression(), clean_all_normalized(), copy_dimension(), copy_expression(), dimension_lower, dimension_undefined, dimension_upper, entity_local_name(), entity_type, expression_undefined, find_ith_argument(), find_ith_dimension(), gen_length(), get_bool_property(), gt_expression, ifdebug, int, lt_expression, make_array_dimension_bound_test(), make_true_array_dimension_bound_test(), number_of_added_checks, number_of_bound_checks, pips_debug, print_expression(), print_reference(), reference_indices, reference_variable, trivial_expression_p(), type_variable, unbounded_dimension_p(), user_log(), variable_dimensions, and variable_in_common_p().

Referenced by bottom_up_abc_expression().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ bottom_up_abc_reference_implied_do()

static array_dimension_bound_test bottom_up_abc_reference_implied_do ( expression  e,
Index_range  ir 
)
static

Treat array reference

For example, we have array reference A(I,J) with two indexes I and J and ranges 1:20 and 1:10, respectively

Definition at line 587 of file array_bound_check_bottom_up.c.

588 {
590  syntax s = expression_syntax(e);
591  tag t = syntax_tag(s);
592  switch (t){
593  case is_syntax_range:
594  break;
595  case is_syntax_call:
596  break;
597  case is_syntax_reference:
598  {
599  /* Treat array reference */
600  reference re = syntax_reference(s);
601  if (array_reference_p(re))
602  {
603  entity ent = reference_variable(re);
604  if (array_need_bound_check_p(ent))
605  {
606  /* For example, we have array reference A(I,J)
607  with two indexes I and J and ranges 1:20 and 1:10, respectively*/
608  list list_index = ir.ind, list_range = ir.ran;
609  while (!ENDP(list_index))
610  {
611  expression ind = EXPRESSION(CAR(list_index));
612  range ran = RANGE(CAR(list_range));
614  temp = bottom_up_abc_base_reference_implied_do(re,ind,ran);
615  retour = add_array_dimension_bound_test(retour,temp);
616  list_index = CDR(list_index);
617  list_range = CDR(list_range);
618  }
619  }
620  }
621  break;
622  }
623  }
624  return retour;
625 }
static array_dimension_bound_test bottom_up_abc_base_reference_implied_do(reference re, expression ind, range ran)

References add_array_dimension_bound_test(), array_dimension_bound_test_undefined, array_need_bound_check_p(), array_reference_p(), bottom_up_abc_base_reference_implied_do(), CAR, CDR, ENDP, EXPRESSION, expression_syntax, Index_range::ind, is_syntax_call, is_syntax_range, is_syntax_reference, Index_range::ran, RANGE, reference_variable, syntax_reference, and syntax_tag.

Referenced by bottom_up_abc_expression_implied_do().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ bottom_up_abc_statement()

static void bottom_up_abc_statement ( statement  module_statement)
static

Definition at line 1077 of file array_bound_check_bottom_up.c.

1078 {
1082 
1087  NULL);
1088 
1090  stack_free(&context.uns);
1091 }
persistant_statement_to_control make_persistant_statement_to_control(void)
Definition: ri.c:1594
void free_persistant_statement_to_control(persistant_statement_to_control p)
Definition: ri.c:1561
static bool push_uns(unstructured u, bottom_up_abc_context_p context)
static bool store_mapping(control c, bottom_up_abc_context_p context)
static void bottom_up_abc_statement_rwt(statement s, bottom_up_abc_context_p context)
static void pop_uns(unstructured u, bottom_up_abc_context_p context)
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
void stack_free(stack *)
type, bucket_size, policy
Definition: stack.c:292
stack stack_make(int, int, int)
allocation
Definition: stack.c:246
#define unstructured_domain
newgen_type_domain_defined
Definition: ri.h:442
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define control_domain
newgen_controlmap_domain_defined
Definition: ri.h:98
context data structure for bottom_up_abc newgen recursion

References bottom_up_abc_statement_rwt(), control_domain, free_persistant_statement_to_control(), gen_context_multi_recurse(), gen_null(), gen_true(), make_persistant_statement_to_control(), module_statement, pop_uns(), push_uns(), stack_free(), stack_make(), statement_domain, store_mapping(), and unstructured_domain.

Referenced by array_bound_check_bottom_up().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ bottom_up_abc_statement_rwt()

static void bottom_up_abc_statement_rwt ( statement  s,
bottom_up_abc_context_p  context 
)
static

because we use gen_recurse with statement domain, we don't have to check unstructured instruction here

Definition at line 984 of file array_bound_check_bottom_up.c.

987 {
989  tag t = instruction_tag(i);
990  statement stmt2;
991 
992  ifdebug(2)
993  {
994  pips_debug(2, "\n Current statement");
995  print_statement(s);
996  }
997  switch(t)
998  {
999  case is_instruction_call:
1000  {
1001  call cal = instruction_call(i);
1003 
1004  if ((stmt2 = cstr_args_check(s)) != statement_undefined) {
1005  printf("Insertion d'un statement ---->\n");
1007  }
1008 
1009  adt = bottom_up_abc_call(cal);
1011  {
1014  }
1015  break;
1016  }
1018  {
1020  // array bound check of while loop condition
1024  {
1027  }
1028  break;
1029  }
1030  case is_instruction_test:
1031  {
1032  test it = instruction_test(i);
1033  // array bound check of the test condition
1034  expression e1 = test_condition(it);
1037  {
1040  }
1041  break;
1042  }
1044  case is_instruction_loop:
1045  // suppose that there are not array references in loop's range in norm
1047  // suppose that there are not array references in loop's range in norm
1049  /* because we use gen_recurse with statement domain,
1050  * we don't have to check unstructured instruction here*/
1051  break;
1052  default:
1053  pips_internal_error("Unexpected instruction tag %d ", t );
1054  break;
1055  }
1056 }
static statement make_bottom_up_abc_tests(array_dimension_bound_test adt)
static void bottom_up_abc_insert_before_statement(statement s, statement s1, bottom_up_abc_context_p context)
static statement cstr_args_check(statement)
forward declaration
#define pips_internal_error
Definition: misc-local.h:149
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_forloop
Definition: ri.h:1477
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define test_condition(x)
Definition: ri.h:2833
#define instruction_whileloop(x)
Definition: ri.h:1523
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
#define instruction_test(x)
Definition: ri.h:1517
#define whileloop_condition(x)
Definition: ri.h:3160
int printf()

References array_dimension_bound_test_undefined_p(), bottom_up_abc_call(), bottom_up_abc_expression(), bottom_up_abc_insert_before_statement(), cstr_args_check(), ifdebug, instruction_call, instruction_tag, instruction_test, instruction_whileloop, is_instruction_call, is_instruction_forloop, is_instruction_loop, is_instruction_sequence, is_instruction_test, is_instruction_unstructured, is_instruction_whileloop, make_bottom_up_abc_tests(), pips_debug, pips_internal_error, print_statement(), printf(), statement_instruction, statement_undefined, test_condition, and whileloop_condition.

Referenced by bottom_up_abc_statement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ bzero_check_expression()

static expression bzero_check_expression ( expression  args[],
int  nargs 
)
static

Definition at line 1501 of file array_bound_check_bottom_up.c.

1502 {
1503  expression arg0_size_expr;
1504 
1505  CHECK_NARGS(2);
1506 
1507  arg0_size_expr = expression_try_find_size(args[0]);
1508  if (arg0_size_expr == expression_undefined)
1509  return expression_undefined;
1510 
1511  return cf_gt_expression(args[1], arg0_size_expr);
1512 }
static expression expression_try_find_size(expression expr)
#define cf_gt_expression(e1, e2)

References cf_gt_expression, CHECK_NARGS, expression_try_find_size(), and expression_undefined.

Referenced by memset_check_expression().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cstr_args_check()

static statement cstr_args_check ( statement  s)
static

forward declaration

Convert the arguments list into an array

Add malloc(), free(), etc. instrumentation

The target languague is unknown: C or Fortran, NL at the end or not? It will be up to the prettyprinter (FI). FI+LD 21-Oct-2009 : added NL, apparently needed in Fortran too.

Definition at line 1805 of file array_bound_check_bottom_up.c.

1806 {
1808  statement astmt;
1809  expression expr, *argstab;
1810  call cal;
1811  list args;
1812  string func_name;
1813  int nargs = 0, k;
1814  struct checkfn *p;
1815 
1816  pips_assert("Statement is a call statmt.",
1818 
1819  cal = instruction_call(i);
1820  func_name = entity_name(call_function(cal));
1821  pips_debug(1, "FONCTION: %s\n", func_name);
1822 
1823  /* Convert the arguments list into an array */
1824  args = call_arguments(cal);
1825  nargs = gen_length(args);
1826  argstab = malloc(sizeof(expression) * nargs);
1827  for (k = 0; k < nargs; k++) {
1828  argstab[k] = EXPRESSION(CAR(args));
1829  args = CDR(args);
1830  }
1831 
1832  /* Add malloc(), free(), etc. instrumentation */
1833  if (strcmp(func_name, "TOP-LEVEL:=") == 0
1834  && (astmt = alloc_instrumentation(argstab, nargs)) != statement_undefined) {
1835  free(argstab);
1836  return astmt;
1837  /*
1838  * free(m); => PIPS_size_m = 0;
1839  * free(m);
1840  */
1841  } else if (strcmp(func_name, "TOP-LEVEL:free") == 0) {
1842  entity arg_ent, size_holder;
1843  string e_uname;
1844 
1845  free(argstab);
1846 
1847  if (!expression_reference_p(argstab[0]))
1848  return statement_undefined;
1849  else {
1851  expression_syntax(argstab[0])));
1852  if (!type_variable_p(entity_type(arg_ent)))
1853  return statement_undefined;
1854  }
1855  e_uname = entity_size_uname(arg_ent);
1856  size_holder = FindEntity("main", e_uname);
1857  free(e_uname);
1858  if (size_holder == entity_undefined)
1859  return statement_undefined;
1860  return make_assign_statement(make_entity_expression(size_holder, NIL),
1861  int_to_expression(0));
1862  }
1863 
1864  if (strncmp(func_name, "TOP-LEVEL:", 10) != 0) {
1865  free(argstab);
1866  return statement_undefined;
1867  }
1868 
1869  expr = expression_undefined;
1870  for (p = checkfns; p->function != NULL; p++) {
1871  if (strcmp(p->function, func_name + 10) == 0) {
1872  expr = (p->check_statement)(argstab, nargs);
1873  break;
1874  }
1875  }
1876 
1877  free(argstab);
1878 
1879  if (expr == expression_undefined) {
1880  /* The target languague is unknown: C or Fortran, NL at the
1881  end or not? It will be up to the prettyprinter (FI).
1882  FI+LD 21-Oct-2009 : added NL, apparently needed in Fortran too.
1883  */
1884  put_a_comment_on_a_statement(s, strdup("CHECK WAS NOT CREATED\n"));
1885  return statement_undefined;
1886  }
1887 
1888  /*
1889  * Add checks for array indices when necessary.
1890  */
1891  for (k = 0; k < nargs; k++)
1892  expr = array_check_add(argstab[k], expr);
1893  return test_to_statement(make_test(expr,
1896 }
test make_test(expression a1, statement a2, statement a3)
Definition: ri.c:2607
static statement alloc_instrumentation(expression args[], int nargs)
static expression array_check_add(expression array_expr, expression expr)
static statement make_c_stop_statement(int abort_program)
static struct checkfn checkfns[]
void * malloc(YYSIZE_T)
void free(void *)
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
void put_a_comment_on_a_statement(statement, string)
Similar to try_to_put_a_comment_on_a_statement() but insert a CONTINUE to put the comment on it if th...
Definition: statement.c:1863
#define test_to_statement(t)
char * strdup()
expression(* check_statement)(expression *, int)

References alloc_instrumentation(), array_check_add(), call_arguments, call_function, CAR, CDR, checkfn::check_statement, checkfns, entity_name, entity_size_uname(), entity_type, entity_undefined, EXPRESSION, expression_reference_p(), expression_syntax, expression_undefined, FindEntity(), free(), checkfn::function, gen_length(), instruction_call, instruction_tag, int_to_expression(), is_instruction_call, make_assign_statement(), make_block_statement(), make_c_stop_statement(), make_entity_expression(), make_test(), malloc(), NIL, pips_assert, pips_debug, put_a_comment_on_a_statement(), reference_variable, statement_instruction, statement_undefined, strdup(), syntax_reference, test_to_statement, and type_variable_p.

Referenced by bottom_up_abc_statement_rwt().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ display_bottom_up_abc_statistics()

static void display_bottom_up_abc_statistics ( )
static

Definition at line 135 of file array_bound_check_bottom_up.c.

136 {
137  if (number_of_bound_checks > 0)
138  {
139  user_log("* There are %d array bound checks *\n",
141  }
142  if (number_of_added_checks > 0)
143  user_log("* There %s %d array bound check%s added *\n",
144  number_of_added_checks > 1 ? "are" : "is",
146  number_of_added_checks > 1 ? "s" : "");
147 
149  user_log("* There %s %d bound violation%s *\n",
150  number_of_bound_violations > 1 ? "are" : "is",
152  number_of_bound_violations > 1 ? "s" : "");
153 }
static int number_of_bound_violations

References number_of_added_checks, number_of_bound_checks, number_of_bound_violations, and user_log().

Referenced by array_bound_check_bottom_up().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ emit_message_and_stop()

statement emit_message_and_stop ( string  stop_message)

Must be the C version

Parameters
stop_messagetop_message

Definition at line 837 of file array_bound_check_bottom_up.c.

838 {
840 
842  //return make_stop_statement(message);
843  smt = make_stop_statement(stop_message);
844  }
845  else {
846  /* Must be the C version */
847  smt = make_exit_statement(1, stop_message);
848  }
849  return smt;
850 }
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
statement make_stop_statement(string)
This function returns a Fortran stop statement with an error message.
Definition: statement.c:908
statement make_exit_statement(int, string)
This function returns a statement ending with a C exit statement.
Definition: statement.c:926
bool fortran_module_p(entity m)
Test if a module is in Fortran.
Definition: entity.c:2799

References fortran_module_p(), get_current_module_entity(), make_exit_statement(), make_stop_statement(), and statement_undefined.

Referenced by make_bottom_up_abc_tests(), and make_c_stop_statement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ entity_constant_string_size()

static int entity_constant_string_size ( entity  e)
static

Definition at line 1212 of file array_bound_check_bottom_up.c.

1213 {
1214  basic b;
1215  type t, result;
1216  value v;
1217  constant c;
1218 
1219  t = entity_type(e);
1220  if (type_functional_p(t)
1222  && basic_string_p((b = variable_basic(type_variable(result))))
1223  && value_constant_p((v = basic_string(b)))
1224  && constant_int_p((c = value_constant(v))))
1225  return constant_int(c);
1226  return -1;
1227 }
#define type_functional_p(x)
Definition: ri.h:2950
#define functional_result(x)
Definition: ri.h:1444
#define value_constant(x)
Definition: ri.h:3073
#define constant_int(x)
Definition: ri.h:850
#define type_functional(x)
Definition: ri.h:2952
#define value_constant_p(x)
Definition: ri.h:3071
#define constant_int_p(x)
Definition: ri.h:848
#define basic_string_p(x)
Definition: ri.h:629
#define basic_string(x)
Definition: ri.h:631

References basic_string, basic_string_p, constant_int, constant_int_p, entity_type, functional_result, type_functional, type_functional_p, type_variable, type_variable_p, value_constant, value_constant_p, and variable_basic.

Referenced by expression_try_find_size(), and expression_try_find_string_size().

+ Here is the caller graph for this function:

◆ entity_size_uname()

static string entity_size_uname ( entity  e)
static

Definition at line 1236 of file array_bound_check_bottom_up.c.

1237 {
1238  static const char prefix []= "PIPS_size_";
1239  string name = entity_name(e);
1240  string uname;
1241  int i, len = strlen(name);
1242 
1243  if ((uname = malloc(len + 1 + sizeof(prefix))) == NULL) {
1244  perror("malloc");
1245  exit(1);
1246  }
1247  sprintf(uname, "%s%s",prefix, name);
1248  len = strlen(uname);
1249  for (i = 0; i < len; i++) {
1250  if (uname[i] == ':' || uname[i] == '-') {
1251  uname[i] = '_';
1252  }
1253  }
1254  return uname;
1255 }
#define exit(code)
Definition: misc-local.h:54
static const char * prefix

References entity_name, exit, malloc(), and prefix.

Referenced by alloc_instrumentation(), cstr_args_check(), and expression_try_find_size().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ expression_in_array_subscript()

static bool expression_in_array_subscript ( expression  e,
list  args 
)
static

We have to consider only the case of Implied DO if e is in the lower or upper bound of implied DO's range or not

range e1,e2,e3

Definition at line 714 of file array_bound_check_bottom_up.c.

715 {
716  MAP(EXPRESSION, exp,
717  {
719  tag t = syntax_tag(s);
720  switch (t){
721  case is_syntax_call:
722  {
723  /* We have to consider only the case of Implied DO
724  * if e is in the lower or upper bound of implied DO's range or not */
726  {
727  call c = syntax_call(s);
728  list cargs = call_arguments(c);
729  expression arg2 = EXPRESSION(CAR(CDR(cargs))); /* range e1,e2,e3*/
731  expression e1 = range_lower(r);
732  expression e2 = range_upper(r);
733  expression e3 = range_increment(r);
734  ifdebug(3)
735  {
736  fprintf(stderr,"\n Implied DO expression:\n");
738  }
739  if (same_expression_p(e,e1)||same_expression_p(e,e2)||same_expression_p(e,e3))
740  return true;
741  }
742  break;
743  }
744  case is_syntax_reference:
745  {
747  if (array_reference_p(ref))
748  {
749  list arrayinds = reference_indices(ref);
750  if (same_expression_in_list_p(e,arrayinds))
751  return true;
752  }
753  break;
754  }
755  case is_syntax_range:
756  break;
757  }
758  },args);
759  return false;
760 }
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...

References array_reference_p(), call_arguments, CAR, CDR, exp, EXPRESSION, expression_implied_do_p(), expression_syntax, fprintf(), ifdebug, is_syntax_call, is_syntax_range, is_syntax_reference, MAP, print_expression(), range_increment, range_lower, range_upper, ref, reference_indices, same_expression_in_list_p(), same_expression_p(), syntax_call, syntax_range, syntax_reference, and syntax_tag.

Referenced by read_statement_with_write_effect_on_array_subscript().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ expression_try_find_size()

static expression expression_try_find_size ( expression  expr)
static

The expression is a string constant

Definition at line 1263 of file array_bound_check_bottom_up.c.

1264 {
1265  syntax syn = expression_syntax(expr);
1266 
1267  /*
1268  * Case of a reference.
1269  *
1270  * Try to find the size of the corresponding buffer.
1271  */
1272  if (expression_reference_p(expr)) {
1275  int s;
1276 
1277  if (type_variable_p(entity_type(e))) {
1279  entity size_holder;
1280  string e_uname;
1281  list dims = variable_dimensions(var);
1282  list acc = reference_indices(ref);
1283 
1284  while (1) {
1285  if (ENDP(acc) && !ENDP(dims)) {
1286  /*
1287  * We found the upper bound of the given
1288  * expression, we need to add one to get the
1289  * size of the buffer
1290  */
1291  expression upper_bound =
1292  dimension_upper(DIMENSION(CAR(dims)));
1293 
1294  if (expression_constant_p(upper_bound)) {
1295  return int_to_expression(1
1296  + expression_to_int(upper_bound));
1297  } else
1298  return make_add_expression(upper_bound,
1299  int_to_expression(1));
1300  } else if (!ENDP(acc) && !ENDP(dims)) {
1301  acc = CDR(acc);
1302  dims = CDR(dims);
1303  }
1304  else
1305  break;
1306  }
1307  /*
1308  * The memory pointed by the variable was probably
1309  * allocated by malloc() (or a similar function).
1310  */
1311  e_uname = entity_size_uname(e);
1312  size_holder = FindOrCreateEntity("main",e_uname);
1313 
1314  free(e_uname);
1315  if (size_holder == entity_undefined)
1316  return expression_undefined;
1317  else
1318  return make_entity_expression(size_holder, NIL);
1319  }
1320  /* The expression is a string constant */
1321  else if ((s = entity_constant_string_size(e)) >= 0)
1322  return int_to_expression(s);
1323  }
1324 
1325  /*
1326  * The expression is a function call.
1327  *
1328  * Only two forms are acceptable here: base + x, or base - y.
1329  */
1330  else if (expression_call_p(expr)) {
1331  call cal = syntax_call(syn);
1332  entity fun = call_function(cal);
1333  string fun_name = entity_name(fun);
1334  list args = call_arguments(cal);
1335  expression base, base_size, x;
1336 
1337  if (strcmp(fun_name, "TOP-LEVEL:+C") == 0) {
1338  base = EXPRESSION(CAR(args));
1339  x = EXPRESSION(CAR(CDR(args)));
1340  base_size = expression_try_find_size(base);
1341  if (base_size == expression_undefined)
1342  return expression_undefined;
1343  else
1344  return make_sub_expression(base_size, x);
1345  } else // XXX traiter le cas de fonctions imbriquï¿œes !
1346  return expression_undefined;
1347  }
1348 
1349  return expression_undefined;
1350 }
static int entity_constant_string_size(entity e)
#define make_sub_expression(e1, e2)
bdt base
Current expression.
Definition: bdt_read_paf.c:100
entity FindOrCreateEntity(const char *package, const char *local_name)
Problem: A functional global entity may be referenced without parenthesis or CALL keyword in a functi...
Definition: entity.c:1586

References base, call_arguments, call_function, CAR, CDR, DIMENSION, dimension_upper, ENDP, entity_constant_string_size(), entity_name, entity_size_uname(), entity_type, entity_undefined, EXPRESSION, expression_call_p(), expression_constant_p(), expression_reference_p(), expression_syntax, expression_to_int(), expression_undefined, FindOrCreateEntity(), free(), int_to_expression(), make_add_expression, make_entity_expression(), make_sub_expression, NIL, ref, reference_indices, reference_variable, syntax_call, syntax_reference, type_variable, type_variable_p, variable_dimensions, and x.

Referenced by bzero_check_expression(), memcpy_check_expression(), strcat_check_expression(), strcpy_check_expression(), strncat_check_expression(), and strncpy_check_expression().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ expression_try_find_string_size()

static expression expression_try_find_string_size ( expression  expr)
static

Definition at line 1364 of file array_bound_check_bottom_up.c.

1365 {
1366  entity e;
1367  int s;
1368 
1370  if (e != entity_undefined && (s = entity_constant_string_size(e)) >= 0)
1371  return int_to_expression(s);
1372  else
1373  return make_strlen_expression(expr);
1374 }
static expression make_strlen_expression(expression arg)
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832

References entity_constant_string_size(), entity_undefined, expression_reference(), int_to_expression(), make_strlen_expression(), and reference_variable.

Referenced by strcat_check_expression(), strcpy_check_expression(), and strncat_check_expression().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ initialize_bottom_up_abc_statistics()

static void initialize_bottom_up_abc_statistics ( )
static

Definition at line 128 of file array_bound_check_bottom_up.c.

129 {
133 }

References number_of_added_checks, number_of_bound_checks, and number_of_bound_violations.

Referenced by array_bound_check_bottom_up().

+ Here is the caller graph for this function:

◆ int_to_dimension()

string int_to_dimension ( int  i)

Warning! Do not modify this file that is automatically generated!

Modify src/Libs/instrumentation/instrumentation-local.h instead, to add your own modifications. header file built by cproto instrumentation-local.h cproto-generated files array_bound_check_bottom_up.c

Definition at line 162 of file array_bound_check_bottom_up.c.

163 {
164  switch(i)
165  {
166  case 0 :
167  return "wrt common size";
168  case 1 :
169  return "1st dimension";
170  case 2 :
171  return "2nd dimension";
172  case 3 :
173  return "3rd dimension";
174  case 4 :
175  return "4th dimension";
176  case 5 :
177  return "5th dimension";
178  case 6 :
179  return "6th dimension";
180  case 7 :
181  return "7th dimension";
182  default:
183  return "Over 7!!!";
184  }
185 }

Referenced by make_bottom_up_abc_tests(), and top_down_abc_array().

+ Here is the caller graph for this function:

◆ make_array_dimension_bound_test()

static array_dimension_bound_test make_array_dimension_bound_test ( entity  e,
int  i,
bool  low,
expression  exp 
)
static

Definition at line 218 of file array_bound_check_bottom_up.c.

219 {
222  {
223  retour.arr = CONS(ENTITY,e,NIL);
224  retour.dim = CONS(INT,i,NIL);
225  retour.bou = CONS(BOOL,low,NIL);
226  retour.exp = CONS(EXPRESSION,exp,NIL);
227  }
228  return retour;
229 }
#define expression_undefined_p(x)
Definition: ri.h:1224

References array_dimension_bound_test::arr, array_dimension_bound_test_undefined, BOOL, array_dimension_bound_test::bou, CONS, array_dimension_bound_test::dim, ENTITY, exp, array_dimension_bound_test::exp, EXPRESSION, expression_undefined_p, INT, and NIL.

Referenced by abc_with_allocation_size(), bottom_up_abc_base_reference_implied_do(), and bottom_up_abc_reference().

+ Here is the caller graph for this function:

◆ make_bin_expression()

static expression make_bin_expression ( string  name,
expression  e1,
expression  e2 
)
static

Definition at line 1146 of file array_bound_check_bottom_up.c.

1147 {
1148  entity add_ent = gen_find_entity(name);
1149 
1150  return make_call_expression(add_ent,
1151  CONS(EXPRESSION, e1, CONS(EXPRESSION, e2, NIL)));
1152 }
entity gen_find_entity(char *s)
Definition: ri.c:2551

References CONS, EXPRESSION, gen_find_entity(), make_call_expression(), and NIL.

+ Here is the call graph for this function:

◆ make_bottom_up_abc_tests()

static statement make_bottom_up_abc_tests ( array_dimension_bound_test  adt)
static

There is a bound violation, we can return a stop statement immediately, but for debugging purpose, it is better to display all bound violations

Definition at line 852 of file array_bound_check_bottom_up.c.

853 {
854  list la = adt.arr,ld = adt.dim,lb = adt.bou,le = adt.exp;
856  string string_delimiter =
858  "\'" : "\"";
859  while (!ENDP(la))
860  {
861  entity a = ENTITY(CAR(la));
862  int d = INT(CAR(ld));
863  bool b = BOOL(CAR(lb));
864  expression e = EXPRESSION(CAR(le));
865  string stop_message =
866  strdup(concatenate(string_delimiter,
867  "Bound violation: array \"",
868  entity_user_name(a),"\", ",
870  string_delimiter, NULL));
871  string print_message =
872  strdup(concatenate(string_delimiter,
873  "BV array \"",entity_user_name(a),"\", ",
874  int_to_dimension(d),bool_to_bound(b),"with ",
876  string_delimiter,
877  print_variables(e), NULL));
879  if (true_expression_p(e))
880  {
882  /* There is a bound violation, we can return a stop statement immediately,
883  but for debugging purpose, it is better to display all bound violations */
884  if (get_bool_property("PROGRAM_VERIFICATION_WITH_PRINT_MESSAGE"))
885  //return make_print_statement(message);
886  smt = make_any_print_statement(print_message);
887  else {
888  smt = emit_message_and_stop(stop_message);
889  }
890  }
891  else
892  {
893  if (get_bool_property("PROGRAM_VERIFICATION_WITH_PRINT_MESSAGE"))
894  smt = test_to_statement(make_test(e, make_print_statement(print_message),
896  else
897  smt = test_to_statement(make_test(e, emit_message_and_stop(stop_message),
899  }
900  if (statement_undefined_p(retour))
901  retour = copy_statement(smt);
902  else
903  // always structured case
904  insert_statement(retour,copy_statement(smt),false);
905  la = CDR(la);
906  ld = CDR(ld);
907  lb = CDR(lb);
908  le = CDR(le);
909  }
910  ifdebug(2)
911  {
912  pips_debug(2,"\n With array bound checks:");
913  print_statement(retour);
914  }
915  return retour;
916 }
statement copy_statement(statement p)
STATEMENT.
Definition: ri.c:2186
statement emit_message_and_stop(string stop_message)
string print_variables(expression e)
string int_to_dimension(int i)
Warning! Do not modify this file that is automatically generated!
string bool_to_bound(bool b)
array_bound_check_top_down.c
statement make_any_print_statement(string)
Generate a print of a constant character string on stderr for C or on stdout for Fortran.
Definition: statement.c:893
statement make_print_statement(string)
Make a Fortran print statement.
Definition: statement.c:835
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
string expression_to_string(expression e)
Definition: expression.c:77
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
#define statement_undefined_p(x)
Definition: ri.h:2420

References array_dimension_bound_test::arr, BOOL, bool_to_bound(), array_dimension_bound_test::bou, CAR, CDR, concatenate(), copy_statement(), array_dimension_bound_test::dim, emit_message_and_stop(), ENDP, ENTITY, entity_user_name(), array_dimension_bound_test::exp, EXPRESSION, expression_to_string(), fortran_module_p(), get_bool_property(), get_current_module_entity(), ifdebug, insert_statement(), INT, int_to_dimension(), make_any_print_statement(), make_block_statement(), make_print_statement(), make_test(), NIL, number_of_bound_violations, pips_debug, print_statement(), print_variables(), statement_undefined, statement_undefined_p, strdup(), test_to_statement, and true_expression_p().

Referenced by bottom_up_abc_statement_rwt().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ make_c_stop_statement()

static statement make_c_stop_statement ( int  abort_program)
static

Definition at line 1168 of file array_bound_check_bottom_up.c.

1169 {
1170  pips_assert("true", abort_program==abort_program);
1171  /*
1172  * XXX 'entity_intrinsic' not verified ...
1173  * Pourtant exit() et abort() sont dï¿œclarï¿œs ds bootstrap.c
1174  */
1175 #if 0
1176  list l = NIL;
1177  string stop_func;
1178 
1179  if (abort_program)
1180  stop_func = "TOP-LEVEL:abort";
1181  else
1182  stop_func = "TOP-LEVEL:exit";
1183 
1184  l = CONS(STATEMENT, make_call_statement(stop_func,
1186  entity_undefined, ""),
1187  l);
1188 
1189  /*
1190  if (get_bool_property("PROGRAM_VERIFICATION_WITH_PRINT_MESSAGE")) {
1191  l = CONS(STATEMENT, make_call_statement("TOP-LEVEL:printf",
1192  CONS(EXPRESSION, string_to_expression(), NIL)
1193  entity_undefined, ""),
1194  l);
1195  }
1196  */
1197 
1198  return make_block_statement(l);
1199 #endif
1200  return emit_message_and_stop("Buffer overflow!");
1201 }
statement make_call_statement(string, list, entity, string)
This function is limited to intrinsics calls...
Definition: statement.c:1274

References CONS, emit_message_and_stop(), entity_undefined, EXPRESSION, int_to_expression(), make_block_statement(), make_call_statement(), NIL, pips_assert, and STATEMENT.

Referenced by cstr_args_check().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ make_strlen_expression()

static expression make_strlen_expression ( expression  arg)
static

Definition at line 1159 of file array_bound_check_bottom_up.c.

1160 {
1161  entity strlen_ent;
1162 
1163  strlen_ent = FindOrCreateTopLevelEntity("strlen");
1164  return make_call_expression(strlen_ent, CONS(EXPRESSION, arg, NIL));
1165 }
entity FindOrCreateTopLevelEntity(const char *name)
Return a top-level entity.
Definition: entity.c:1603

References CONS, EXPRESSION, FindOrCreateTopLevelEntity(), make_call_expression(), and NIL.

Referenced by expression_try_find_string_size().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ make_true_array_dimension_bound_test()

static array_dimension_bound_test make_true_array_dimension_bound_test ( entity  e,
int  i,
bool  low 
)
static

Definition at line 206 of file array_bound_check_bottom_up.c.

207 {
210  retour.arr = CONS(ENTITY,e,NIL);
211  retour.dim = CONS(INT,i,NIL);
212  retour.bou = CONS(BOOL,low,NIL);
213  retour.exp = CONS(EXPRESSION,exp,NIL);
214  return retour;
215 }
expression make_true_expression()
Definition: expression.c:1103

References array_dimension_bound_test::arr, BOOL, array_dimension_bound_test::bou, CONS, array_dimension_bound_test::dim, ENTITY, exp, array_dimension_bound_test::exp, EXPRESSION, INT, make_true_expression(), and NIL.

Referenced by abc_with_allocation_size(), bottom_up_abc_base_reference_implied_do(), and bottom_up_abc_reference().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ memcmp_check_expression()

static expression memcmp_check_expression ( expression  args[],
int  nargs 
)
static

Definition at line 1520 of file array_bound_check_bottom_up.c.

1521 {
1522  CHECK_NARGS(3);
1523  return memcpy_check_expression(args, nargs);
1524 }

References CHECK_NARGS, and memcpy_check_expression().

+ Here is the call graph for this function:

◆ memcpy_check_expression()

static expression memcpy_check_expression ( expression  args[],
int  nargs 
)
static

Definition at line 1454 of file array_bound_check_bottom_up.c.

1455 {
1456  expression arg0_size_expr, arg1_size_expr;
1457  CHECK_NARGS(3);
1458 
1459  arg0_size_expr = expression_try_find_size(args[0]);
1460  arg1_size_expr = expression_try_find_size(args[1]);
1461  if (arg0_size_expr == expression_undefined
1462  || arg1_size_expr == expression_undefined)
1463  return expression_undefined;
1464 
1465  return cf_or_expression(
1466  cf_gt_expression(args[2], arg1_size_expr),
1467  cf_gt_expression(args[2], arg0_size_expr));
1468 }
#define cf_or_expression(e1, e2)

References cf_gt_expression, cf_or_expression, CHECK_NARGS, expression_try_find_size(), and expression_undefined.

Referenced by bcmp_check_expression(), bcopy_check_expression(), and memcmp_check_expression().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ memmove_check_expression()

static expression memmove_check_expression ( expression  args[],
int  nargs 
)
static

Convert memmove(dst, src, n) -> bcopy(src, dest, n)

Definition at line 1533 of file array_bound_check_bottom_up.c.

1534 {
1535  expression tmp;
1536  CHECK_NARGS(3);
1537 
1538  /* Convert memmove(dst, src, n) -> bcopy(src, dest, n) */
1539  tmp = args[0];
1540  args[0] = args[1];
1541  args[1] = tmp;
1542  return bcopy_check_expression(args, nargs);
1543 }
static expression bcopy_check_expression(expression args[], int nargs)

References bcopy_check_expression(), and CHECK_NARGS.

+ Here is the call graph for this function:

◆ memset_check_expression()

static expression memset_check_expression ( expression  args[],
int  nargs 
)
static

Convert memset(dst, b, n) -> bzero(dst, n)

Definition at line 1551 of file array_bound_check_bottom_up.c.

1552 {
1553  CHECK_NARGS(3);
1554 
1555  /* Convert memset(dst, b, n) -> bzero(dst, n) */
1556  args[1] = args[2];
1557  return bzero_check_expression(args, 2);
1558 }
static expression bzero_check_expression(expression args[], int nargs)

References bzero_check_expression(), and CHECK_NARGS.

+ Here is the call graph for this function:

◆ pop_uns()

static void pop_uns ( unstructured  u,
bottom_up_abc_context_p  context 
)
static

Definition at line 1071 of file array_bound_check_bottom_up.c.

1072 {
1073  pips_assert("true", u==u && context==context);
1074  stack_pop(context->uns);
1075 }
void * stack_pop(stack)
POPs one item from stack s.
Definition: stack.c:399

References pips_assert, and stack_pop().

Referenced by bottom_up_abc_statement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ print_variables()

string print_variables ( expression  e)

Definition at line 804 of file array_bound_check_bottom_up.c.

805 {
806  syntax s = expression_syntax(e);
807  tag t = syntax_tag(s);
808  string retour = "";
809  switch (t){
810  case is_syntax_range:
811  break;
812  case is_syntax_call:
813  {
814  call c = syntax_call(s);
815  list args = call_arguments(c);
817  {
818  retour = strdup(concatenate(retour,print_variables(exp),NULL));
819  },args);
820  break;
821  }
822  case is_syntax_reference:
823  {
825  retour = strdup(concatenate(retour,", \', ",reference_to_string(ref)," =\',",
826  reference_to_string(ref),NULL));
827  break;
828  }
829  default:
830  {
831  pips_internal_error("Unexpected expression tag %d ", t );
832  break;
833  }
834  }
835  return retour;
836 }
string reference_to_string(reference r)
Definition: expression.c:87

References call_arguments, concatenate(), exp, EXPRESSION, expression_syntax, is_syntax_call, is_syntax_range, is_syntax_reference, MAP, pips_internal_error, ref, reference_to_string(), strdup(), syntax_call, syntax_reference, and syntax_tag.

Referenced by make_bottom_up_abc_tests(), and make_interprocedural_abc_tests().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ push_uns()

static bool push_uns ( unstructured  u,
bottom_up_abc_context_p  context 
)
static

Definition at line 1065 of file array_bound_check_bottom_up.c.

1066 {
1067  stack_push((char *) u, context->uns);
1068  return true;
1069 }
void stack_push(void *, stack)
stack use
Definition: stack.c:373

References stack_push().

Referenced by bottom_up_abc_statement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ read_statement_with_write_effect_on_array_subscript()

static bool read_statement_with_write_effect_on_array_subscript ( call  c)
static

Definition at line 762 of file array_bound_check_bottom_up.c.

763 {
764  entity func = call_function(c);
765  if (strcmp(entity_local_name(func),READ_FUNCTION_NAME)==0)
766  {
767  list args = call_arguments(c);
768  while (!ENDP(args))
769  {
770  expression exp = EXPRESSION(CAR(args));
771  args = CDR(args);
773  return true;
774  }
775  }
776  return false;
777 }
static bool expression_in_array_subscript(expression e, list args)
#define READ_FUNCTION_NAME

References call_arguments, call_function, CAR, CDR, ENDP, entity_local_name(), exp, EXPRESSION, expression_in_array_subscript(), and READ_FUNCTION_NAME.

Referenced by bottom_up_abc_call().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ snprintf_check_expression()

static expression snprintf_check_expression ( expression  args[],
int  nargs 
)
static

Definition at line 1696 of file array_bound_check_bottom_up.c.

1697 {
1698  if (nargs < 3)
1699  return expression_undefined;
1700  args[2] = args[1];
1701 
1702  return strncpy_check_expression(args, 3);
1703 }
static expression strncpy_check_expression(expression args[], int nargs)

References expression_undefined, and strncpy_check_expression().

+ Here is the call graph for this function:

◆ sprintf_check_expression()

static expression sprintf_check_expression ( expression  args[],
int  nargs 
)
static

Definition at line 1660 of file array_bound_check_bottom_up.c.

1661 {
1662  int k;
1663  list snprintf_args = NIL;
1664  expression dst_size=expression_undefined, tmpbuf_expr;
1665  entity snprintf_ent, tmpbuf_ent;
1666 
1667  if (nargs < 2)
1668  return expression_undefined;
1669 
1670  if ((snprintf_ent = FindEntity(TOP_LEVEL_MODULE_NAME,"snprintf"))
1671  == entity_undefined)
1672  return expression_undefined;
1673 
1674  if ((tmpbuf_ent = FindEntity("main","PIPS_tmpbuf")) == entity_undefined)
1675  // XXX module "main" non correct
1676  tmpbuf_ent = make_scalar_entity("PIPS_tmpbuf", "main",
1677  make_basic_int(1));
1678  // XXX Il faut &PIPS_tmpbuf
1679  tmpbuf_expr = make_entity_expression(tmpbuf_ent, NIL);
1680 
1681  for (k = nargs - 1; k >= 2; k--)
1682  snprintf_args = CONS(EXPRESSION, args[k], snprintf_args);
1683  snprintf_args = CONS(EXPRESSION, tmpbuf_expr,
1684  CONS(EXPRESSION, int_to_expression(1), snprintf_args));
1685 
1686  return cf_gt_expression(make_call_expression(snprintf_ent, snprintf_args),
1687  dst_size);
1688 }
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101

References cf_gt_expression, CONS, entity_undefined, EXPRESSION, expression_undefined, FindEntity(), int_to_expression(), make_basic_int(), make_call_expression(), make_entity_expression(), make_scalar_entity(), NIL, and TOP_LEVEL_MODULE_NAME.

+ Here is the call graph for this function:

◆ store_mapping()

static bool store_mapping ( control  c,
bottom_up_abc_context_p  context 
)
static

Definition at line 1058 of file array_bound_check_bottom_up.c.

1059 {
1061  control_statement(c), c);
1062  return true;
1063 }
void extend_persistant_statement_to_control(persistant_statement_to_control f, statement k, control v)
Definition: ri.c:1603
#define control_statement(x)
Definition: ri.h:941

References control_statement, and extend_persistant_statement_to_control().

Referenced by bottom_up_abc_statement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ strcat_check_expression()

static expression strcat_check_expression ( expression  args[],
int  nargs 
)
static

Definition at line 1616 of file array_bound_check_bottom_up.c.

1617 {
1618  expression dst_size;
1619 
1620  CHECK_NARGS(2);
1621 
1622  dst_size = expression_try_find_size(args[0]);
1623  if (dst_size == expression_undefined)
1624  return expression_undefined;
1625 
1626  return cf_ge_expression(
1629  dst_size);
1630 }
static expression expression_try_find_string_size(expression expr)
#define cf_ge_expression(e1, e2)

References cf_ge_expression, CHECK_NARGS, expression_try_find_size(), expression_try_find_string_size(), expression_undefined, and make_add_expression.

+ Here is the call graph for this function:

◆ strcpy_check_expression()

static expression strcpy_check_expression ( expression  args[],
int  nargs 
)
static

Definition at line 1566 of file array_bound_check_bottom_up.c.

1567 {
1568  //statement smt;
1569  expression arg1_size_expr ;
1570 
1571  CHECK_NARGS(2);
1572 
1573  arg1_size_expr = expression_try_find_size(args[0]);
1574  if (arg1_size_expr == expression_undefined)
1575  return expression_undefined;
1576  /*
1577  expression arg2_size_expr;
1578  int arg2size;
1579  entity arg2ent;
1580  arg2ent = reference_variable(expression_reference(args[1]));
1581 
1582  if ((arg2size = entity_constant_string_size(arg2ent)) >= 0)
1583  arg2_size_expr = int_to_expression(arg2size);
1584  else
1585  arg2_size_expr = make_strlen_expression(args[1]);
1586  */
1587 
1588  return cf_ge_expression(expression_try_find_string_size(args[1]), arg1_size_expr);
1589 }

References cf_ge_expression, CHECK_NARGS, expression_try_find_size(), expression_try_find_string_size(), and expression_undefined.

+ Here is the call graph for this function:

◆ strncat_check_expression()

static expression strncat_check_expression ( expression  args[],
int  nargs 
)
static

Definition at line 1638 of file array_bound_check_bottom_up.c.

1639 {
1640  expression dst_size;
1641 
1642  CHECK_NARGS(3);
1643 
1644  dst_size = expression_try_find_size(args[0]);
1645  if (dst_size == expression_undefined)
1646  return expression_undefined;
1647  return cf_ge_expression(args[2], make_sub_expression(dst_size,
1649 }

References cf_ge_expression, CHECK_NARGS, expression_try_find_size(), expression_try_find_string_size(), expression_undefined, and make_sub_expression.

+ Here is the call graph for this function:

◆ strncpy_check_expression()

static expression strncpy_check_expression ( expression  args[],
int  nargs 
)
static

Definition at line 1597 of file array_bound_check_bottom_up.c.

1598 {
1599  expression arg1_size_expr;
1600 
1601  CHECK_NARGS(3);
1602 
1603  arg1_size_expr = expression_try_find_size(args[0]);
1604  if (arg1_size_expr == expression_undefined)
1605  return expression_undefined;
1606 
1607  return cf_ge_expression(args[2], arg1_size_expr);
1608 }

References cf_ge_expression, CHECK_NARGS, expression_try_find_size(), and expression_undefined.

Referenced by snprintf_check_expression().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ subscript_value()

expression subscript_value ( entity  arr,
list  l_inds 
)
Parameters
arrrr
l_inds_inds

Definition at line 276 of file array_bound_check_bottom_up.c.

277 {
278  expression retour = int_to_expression(1);
279  if (!ENDP(l_inds))
280  {
281  variable var = type_variable(entity_type(arr));
283  list l_dims = variable_dimensions(var);
284  int num_dim = gen_length(l_inds),i;
285  for (i=1; i<= num_dim; i++)
286  {
287  dimension dim_i = find_ith_dimension(l_dims,i);
288  expression lower_i = dimension_lower(dim_i);
289  expression sub_i = find_ith_argument(l_inds,i);
290  expression upper_i = dimension_upper(dim_i);
291  expression size_i;
292  if ( expression_constant_p(lower_i) && (expression_to_int(lower_i)==1))
293  size_i = copy_expression(upper_i);
294  else
295  {
296  size_i = binary_intrinsic_expression(MINUS_OPERATOR_NAME,upper_i,lower_i);
299  }
300  if (!same_expression_p(sub_i,lower_i))
301  {
303  sub_i,lower_i);
304  expression elem_i;
305  if (expression_undefined_p(prod))
306  elem_i = copy_expression(sub_low_i);
307  else
309  sub_low_i,prod);
311  retour, elem_i);
312  }
313  if (expression_undefined_p(prod))
314  prod = copy_expression(size_i);
315  else
317  prod,size_i);
318  }
319  }
320  ifdebug(4)
321  {
322  pips_debug(4,"\nSubscript value:");
323  print_expression(retour);
324  }
325  return retour;
326 }
#define MINUS_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define binary_intrinsic_expression(name, e1, e2)

References binary_intrinsic_expression, copy_expression(), dimension_lower, dimension_upper, ENDP, entity_type, expression_constant_p(), expression_to_int(), expression_undefined, expression_undefined_p, find_ith_argument(), find_ith_dimension(), gen_length(), ifdebug, int_to_expression(), MINUS_OPERATOR_NAME, MULTIPLY_OPERATOR_NAME, pips_debug, PLUS_OPERATOR_NAME, print_expression(), same_expression_p(), type_variable, and variable_dimensions.

Referenced by abc_with_allocation_size().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ checkfns

struct checkfn checkfns[]
static
Initial value:
= {
{ "bcopy", bcopy_check_expression },
{ "bcmp", bcmp_check_expression },
{ "bzero", bzero_check_expression },
{ "memcmp", memcmp_check_expression },
{ "memcpy", memcpy_check_expression },
{ "memmove", memmove_check_expression },
{ "memset", memset_check_expression },
{ "strcpy", strcpy_check_expression },
{ "strncpy", strncpy_check_expression },
{ "strcat", strcat_check_expression },
{ "strncat", strncat_check_expression },
{ "sprintf", sprintf_check_expression },
{ "snprintf", snprintf_check_expression },
{ NULL, NULL }
}
static expression sprintf_check_expression(expression args[], int nargs)
static expression bcmp_check_expression(expression args[], int nargs)
static expression snprintf_check_expression(expression args[], int nargs)
static expression memcmp_check_expression(expression args[], int nargs)
static expression strncat_check_expression(expression args[], int nargs)
static expression memmove_check_expression(expression args[], int nargs)
static expression strcpy_check_expression(expression args[], int nargs)
static expression memset_check_expression(expression args[], int nargs)
static expression strcat_check_expression(expression args[], int nargs)

Referenced by cstr_args_check().

◆ number_of_added_checks

◆ number_of_bound_checks

◆ number_of_bound_violations

int number_of_bound_violations
static