stage3/array_range_check.cc
author Edouard Tisserant
Fri, 22 Jul 2022 09:24:12 +0200
changeset 1099 cdb045e8be20
parent 1041 56ebe2a31b5b
child 1101 f7a0e962650d
permissions -rw-r--r--
In VARIABLES.CSV, RETAIN variable were only flagged as such for GLOBALS, now local POU variable shoud be as well.
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     1
/*
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     2
 *  matiec - a compiler for the programming languages defined in IEC 61131-3
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     3
 *
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     4
 *  Copyright (C) 2009-2012  Mario de Sousa (msousa@fe.up.pt)
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     5
 *  Copyright (C) 2012       Manuele Conti  (conti.ma@alice.it)
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     6
 *
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     7
 *
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     8
 *  This program is free software: you can redistribute it and/or modify
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     9
 *  it under the terms of the GNU General Public License as published by
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    10
 *  the Free Software Foundation, either version 3 of the License, or
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    11
 *  (at your option) any later version.
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    12
 *
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    13
 *  This program is distributed in the hope that it will be useful,
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    16
 *  GNU General Public License for more details.
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    17
 *
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    18
 *  You should have received a copy of the GNU General Public License
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    19
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    20
 *
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    21
 *
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    22
 * This code is made available on the understanding that it will not be
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    23
 * used in safety-critical situations without a full and competent review.
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    24
 */
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    25
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    26
/*
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    27
 * An IEC 61131-3 compiler.
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    28
 *
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    29
 * Based on the
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    30
 * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    31
 *
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    32
 */
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    33
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    34
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    35
/*
614
31bda4cde875 Fix comment (bug found by Manuele).
Mario de Sousa <msousa@fe.up.pt>
parents: 612
diff changeset
    36
 * Array Range Checking:
31bda4cde875 Fix comment (bug found by Manuele).
Mario de Sousa <msousa@fe.up.pt>
parents: 612
diff changeset
    37
 *   - Check whether array subscript values fall within the allowed range.
31bda4cde875 Fix comment (bug found by Manuele).
Mario de Sousa <msousa@fe.up.pt>
parents: 612
diff changeset
    38
 *     Note that for the checking of subscript values to work correctly, we need to have constant folding working too:
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    39
 *     array_var[8 + 99] can not be checked without constant folding.
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    40
 */
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    41
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    42
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
    43
#include "array_range_check.hh"
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
    44
#include <limits>  // required for std::numeric_limits<XXX>
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
    45
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    46
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    47
#define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order)   ? (symbol1) : (symbol2))
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    48
#define  LAST_(symbol1, symbol2) (((symbol1)->last_order  > (symbol2)->last_order)    ? (symbol1) : (symbol2))
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    49
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    50
#define STAGE3_ERROR(error_level, symbol1, symbol2, ...) {                                                                  \
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    51
  if (current_display_error_level >= error_level) {                                                                         \
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    52
    fprintf(stderr, "%s:%d-%d..%d-%d: error: ",                                                                             \
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    53
            FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    54
                                                 LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);\
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    55
    fprintf(stderr, __VA_ARGS__);                                                                                           \
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    56
    fprintf(stderr, "\n");                                                                                                  \
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    57
    error_count++;                                                                                                     \
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    58
  }                                                                                                                         \
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    59
}
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    60
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    61
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    62
#define STAGE3_WARNING(symbol1, symbol2, ...) {                                                                             \
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    63
    fprintf(stderr, "%s:%d-%d..%d-%d: warning: ",                                                                           \
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    64
            FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    65
                                                 LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);\
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    66
    fprintf(stderr, __VA_ARGS__);                                                                                           \
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    67
    fprintf(stderr, "\n");                                                                                                  \
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    68
    warning_found = true;                                                                                                   \
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    69
}
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    70
965
c9eeb67ba939 Small code re-organization of how const values are stored in symbol_c (can now be accessed through member functions, instead of macros)
mjsousa
parents: 964
diff changeset
    71
c9eeb67ba939 Small code re-organization of how const values are stored in symbol_c (can now be accessed through member functions, instead of macros)
mjsousa
parents: 964
diff changeset
    72
#define GET_CVALUE(dtype, symbol)             ((symbol)->const_value._##dtype.get())
c9eeb67ba939 Small code re-organization of how const values are stored in symbol_c (can now be accessed through member functions, instead of macros)
mjsousa
parents: 964
diff changeset
    73
#define VALID_CVALUE(dtype, symbol)           ((symbol)->const_value._##dtype.is_valid())
581
1e158dc9f9c1 Add check array out of bound.
Manuele Conti <conti.ma@alice.it>
parents: 560
diff changeset
    74
620
aef32856eeb5 Remove warning about comparisons between int and unsigned int.
Manuele Conti <conti.ma@alice.it>
parents: 614
diff changeset
    75
/*  The cmp_unsigned_signed function compares two numbers u and s.
aef32856eeb5 Remove warning about comparisons between int and unsigned int.
Manuele Conti <conti.ma@alice.it>
parents: 614
diff changeset
    76
 *  It returns an integer indicating the relationship between the numbers:
aef32856eeb5 Remove warning about comparisons between int and unsigned int.
Manuele Conti <conti.ma@alice.it>
parents: 614
diff changeset
    77
 *  - A zero value indicates that both numbers are equal.
aef32856eeb5 Remove warning about comparisons between int and unsigned int.
Manuele Conti <conti.ma@alice.it>
parents: 614
diff changeset
    78
 *  - A value greater than zero indicates that numbers does not match and
aef32856eeb5 Remove warning about comparisons between int and unsigned int.
Manuele Conti <conti.ma@alice.it>
parents: 614
diff changeset
    79
 *    first has a greater value.
aef32856eeb5 Remove warning about comparisons between int and unsigned int.
Manuele Conti <conti.ma@alice.it>
parents: 614
diff changeset
    80
 *  - A value less than zero indicates that numbers does not match and
aef32856eeb5 Remove warning about comparisons between int and unsigned int.
Manuele Conti <conti.ma@alice.it>
parents: 614
diff changeset
    81
 *    first has a lesser value.
aef32856eeb5 Remove warning about comparisons between int and unsigned int.
Manuele Conti <conti.ma@alice.it>
parents: 614
diff changeset
    82
 */
aef32856eeb5 Remove warning about comparisons between int and unsigned int.
Manuele Conti <conti.ma@alice.it>
parents: 614
diff changeset
    83
static inline int cmp_unsigned_signed(const uint64_t u, const int64_t s) {
621
e3616f6b6959 Remove remaining signed/unsigned comparison error messages when compiling.
Mario de Sousa <msousa@fe.up.pt>
parents: 620
diff changeset
    84
  const uint64_t INT64_MAX_uvar = INT64_MAX;
e3616f6b6959 Remove remaining signed/unsigned comparison error messages when compiling.
Mario de Sousa <msousa@fe.up.pt>
parents: 620
diff changeset
    85
  if (u <= INT64_MAX_uvar)
620
aef32856eeb5 Remove warning about comparisons between int and unsigned int.
Manuele Conti <conti.ma@alice.it>
parents: 614
diff changeset
    86
    return ((int64_t)u - s);
aef32856eeb5 Remove warning about comparisons between int and unsigned int.
Manuele Conti <conti.ma@alice.it>
parents: 614
diff changeset
    87
  return -1;
aef32856eeb5 Remove warning about comparisons between int and unsigned int.
Manuele Conti <conti.ma@alice.it>
parents: 614
diff changeset
    88
}
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    89
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
    90
array_range_check_c::array_range_check_c(symbol_c *ignore) {
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    91
	error_count = 0;
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    92
	current_display_error_level = 0;
661
f537c3315f83 Minor changes needed to build with pedantic flag.
Manuele Conti <conti.ma@alice.it>
parents: 647
diff changeset
    93
	search_varfb_instance_type = NULL;
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    94
}
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    95
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
    96
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
    97
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
    98
array_range_check_c::~array_range_check_c(void) {
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    99
}
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   100
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   101
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   102
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   103
int array_range_check_c::get_error_count() {
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   104
	return error_count;
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   105
}
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   106
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   107
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   108
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   109
void array_range_check_c::check_dimension_count(array_variable_c *symbol) {
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   110
	int dimension_count;
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   111
	symbol_c *var_decl;
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   112
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   113
	var_decl = search_varfb_instance_type->get_basetype_decl(symbol->subscripted_variable);
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   114
	array_dimension_iterator_c array_dimension_iterator(var_decl);
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   115
	for (dimension_count = 0; NULL != array_dimension_iterator.next(); dimension_count++);
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   116
	if (dimension_count != ((list_c *)symbol->subscript_list)->n)
583
e1df3781be84 Fix array index bound check to consider uint64 indexes/limits.
Mario de Sousa <msousa@fe.up.pt>
parents: 581
diff changeset
   117
		STAGE3_ERROR(0, symbol, symbol, "Number of subscripts/indexes does not match the number of subscripts/indexes in the array's declaration (array has %d indexes)", dimension_count);
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   118
}
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   119
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   120
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   121
581
1e158dc9f9c1 Add check array out of bound.
Manuele Conti <conti.ma@alice.it>
parents: 560
diff changeset
   122
void array_range_check_c::check_bounds(array_variable_c *symbol) {
583
e1df3781be84 Fix array index bound check to consider uint64 indexes/limits.
Mario de Sousa <msousa@fe.up.pt>
parents: 581
diff changeset
   123
  list_c *l; /* the subscript_list */
581
1e158dc9f9c1 Add check array out of bound.
Manuele Conti <conti.ma@alice.it>
parents: 560
diff changeset
   124
  symbol_c *var_decl;
1e158dc9f9c1 Add check array out of bound.
Manuele Conti <conti.ma@alice.it>
parents: 560
diff changeset
   125
1e158dc9f9c1 Add check array out of bound.
Manuele Conti <conti.ma@alice.it>
parents: 560
diff changeset
   126
  l = (list_c *)symbol->subscript_list;
1e158dc9f9c1 Add check array out of bound.
Manuele Conti <conti.ma@alice.it>
parents: 560
diff changeset
   127
  var_decl = search_varfb_instance_type->get_basetype_decl(symbol->subscripted_variable);
1e158dc9f9c1 Add check array out of bound.
Manuele Conti <conti.ma@alice.it>
parents: 560
diff changeset
   128
  array_dimension_iterator_c array_dimension_iterator(var_decl);
1e158dc9f9c1 Add check array out of bound.
Manuele Conti <conti.ma@alice.it>
parents: 560
diff changeset
   129
  for (int i =  0; i < l->n; i++) {
1e158dc9f9c1 Add check array out of bound.
Manuele Conti <conti.ma@alice.it>
parents: 560
diff changeset
   130
    subrange_c *dimension = array_dimension_iterator.next();
585
be7330d9b65c Remove potential access to NULL pointer.
Mario de Sousa <msousa@fe.up.pt>
parents: 583
diff changeset
   131
    /* mismatch between number of indexes/subscripts. This error will be caught in check_dimension_count() so we ignore it. */
be7330d9b65c Remove potential access to NULL pointer.
Mario de Sousa <msousa@fe.up.pt>
parents: 583
diff changeset
   132
    if (NULL == dimension) 
be7330d9b65c Remove potential access to NULL pointer.
Mario de Sousa <msousa@fe.up.pt>
parents: 583
diff changeset
   133
      return;
599
60f3edcf6a8f fix array bounds check.
Mario de Sousa <msousa@fe.up.pt>
parents: 598
diff changeset
   134
60f3edcf6a8f fix array bounds check.
Mario de Sousa <msousa@fe.up.pt>
parents: 598
diff changeset
   135
    /* Check lower limit */
1041
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   136
    if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE( int64, dimension->lower_limit))
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   137
      if ( GET_CVALUE( int64, l->get_element(i)) < GET_CVALUE( int64, dimension->lower_limit) )
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   138
      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be >= %"PRId64").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE( int64, dimension->lower_limit)); continue;}
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   139
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   140
    if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->lower_limit))
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   141
      if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->lower_limit), GET_CVALUE( int64, l->get_element(i))) > 0 )
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   142
      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be >= %"PRIu64").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE(uint64, dimension->lower_limit)); continue;}
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   143
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   144
    if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->lower_limit))
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   145
      if ( GET_CVALUE(uint64, l->get_element(i))   <  GET_CVALUE(uint64, dimension->lower_limit))
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   146
      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be >= %"PRIu64").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE(uint64, dimension->lower_limit)); continue;}
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   147
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   148
    if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE( int64, dimension->lower_limit))
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   149
      if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->lower_limit)) < 0 )
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   150
      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be >= %"PRId64").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->lower_limit)); continue;}
599
60f3edcf6a8f fix array bounds check.
Mario de Sousa <msousa@fe.up.pt>
parents: 598
diff changeset
   151
60f3edcf6a8f fix array bounds check.
Mario de Sousa <msousa@fe.up.pt>
parents: 598
diff changeset
   152
    /* Repeat the same check, now for upper limit */
1041
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   153
    if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE( int64, dimension->upper_limit))
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   154
      if ( GET_CVALUE( int64, l->get_element(i))   >  GET_CVALUE( int64, dimension->upper_limit))
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   155
      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be <= %"PRId64").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE( int64, dimension->upper_limit)); continue;}
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   156
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   157
    if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->upper_limit))
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   158
      if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->upper_limit), GET_CVALUE( int64, l->get_element(i))) < 0 )
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   159
      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be <= %"PRIu64").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE(uint64, dimension->upper_limit)); continue;}
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   160
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   161
    if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->upper_limit))
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   162
      if ( GET_CVALUE(uint64, l->get_element(i))   >  GET_CVALUE(uint64, dimension->upper_limit))
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   163
      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be <= %"PRIu64").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE(uint64, dimension->upper_limit)); continue;}
594
c8092e909886 Clean up code (remove parsing of integers in stage 4).
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   164
      
1041
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   165
    if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE( int64, dimension->upper_limit))
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   166
      if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->upper_limit)) > 0 )
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 977
diff changeset
   167
      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be <= %"PRId64").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->upper_limit)); continue;}
599
60f3edcf6a8f fix array bounds check.
Mario de Sousa <msousa@fe.up.pt>
parents: 598
diff changeset
   168
      
581
1e158dc9f9c1 Add check array out of bound.
Manuele Conti <conti.ma@alice.it>
parents: 560
diff changeset
   169
  }
1e158dc9f9c1 Add check array out of bound.
Manuele Conti <conti.ma@alice.it>
parents: 560
diff changeset
   170
}
1e158dc9f9c1 Add check array out of bound.
Manuele Conti <conti.ma@alice.it>
parents: 560
diff changeset
   171
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   172
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   173
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   174
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   175
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   176
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   177
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   178
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   179
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   180
/*************************/
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   181
/* B.1 - Common elements */
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   182
/*************************/
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   183
/**********************/
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   184
/* B.1.3 - Data types */
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   185
/**********************/
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   186
/********************************/
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   187
/* B 1.3.3 - Derived data types */
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   188
/********************************/
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   189
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   190
/*  signed_integer DOTDOT signed_integer */
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   191
/* dimension will be filled in during stage 3 (array_range_check_c) with the number of elements in this subrange */
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   192
// SYM_REF2(subrange_c, lower_limit, upper_limit, unsigned long long int dimension)
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   193
void *array_range_check_c::visit(subrange_c *symbol) {
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   194
	unsigned long long int dimension = 0; // we use unsigned long long instead of uint64_t since it might just happen to be larger than uint64_t in the platform used for compiling this code!!
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   195
598
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   196
	/* Determine the size of the array... */
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   197
	if        (VALID_CVALUE( int64, symbol->upper_limit) && VALID_CVALUE( int64, symbol->lower_limit)) {  
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   198
		// do the sums in such a way that no overflow is possible... even during intermediate steps used by compiler!
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   199
		// remember that the result (dimension) is unsigned, while the operands are signed!!
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   200
		// dimension = GET_CVALUE( int64, symbol->upper_limit) - VALID_CVALUE( int64, symbol->lower_limit);
975
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   201
		if  (GET_CVALUE( int64, symbol->lower_limit)  >   GET_CVALUE( int64, symbol->upper_limit)) {
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   202
			STAGE3_ERROR(0, symbol, symbol, "Subrange has lower limit (%"PRId64") larger than upper limit (%"PRId64").", GET_CVALUE( int64, symbol->lower_limit), GET_CVALUE( int64, symbol->upper_limit));
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   203
			dimension = std::numeric_limits< unsigned long long int >::max() - 1; // -1 because it will be incremented at the end of this function!! 
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   204
		} else if (GET_CVALUE( int64, symbol->lower_limit) >= 0) {
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   205
			dimension = GET_CVALUE( int64, symbol->upper_limit) - GET_CVALUE( int64, symbol->lower_limit);
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   206
		} else {
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   207
			dimension  = -GET_CVALUE( int64, symbol->lower_limit);
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   208
			dimension +=  GET_CVALUE( int64, symbol->upper_limit);     
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   209
		}
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   210
	} else if (VALID_CVALUE(uint64, symbol->upper_limit) && VALID_CVALUE(uint64, symbol->lower_limit)) {
975
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   211
		if  (GET_CVALUE(uint64, symbol->lower_limit)  >   GET_CVALUE(uint64, symbol->upper_limit)) {
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   212
			STAGE3_ERROR(0, symbol, symbol, "Subrange has lower limit (%"PRIu64") larger than upper limit (%"PRIu64").", GET_CVALUE(uint64, symbol->lower_limit), GET_CVALUE(uint64, symbol->upper_limit));
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   213
			dimension = std::numeric_limits< unsigned long long int >::max() - 1; // -1 because it will be incremented at the end of this function!! 
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   214
		} else
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   215
			dimension = GET_CVALUE(uint64, symbol->upper_limit) - GET_CVALUE(uint64, symbol->lower_limit); 
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   216
	} else if (VALID_CVALUE(uint64, symbol->upper_limit) && VALID_CVALUE( int64, symbol->lower_limit)) {
975
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   217
		// No need to check whether lower_limit > upper_limit, as we only reach this point if lower_limit < 0 (and upper_limit must be >= 0!)
598
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   218
		if (GET_CVALUE( int64, symbol->lower_limit) >= 0) {
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   219
			dimension = GET_CVALUE(uint64, symbol->upper_limit) - GET_CVALUE( int64, symbol->lower_limit);
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   220
		} else {
598
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   221
			unsigned long long int lower_ull;
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   222
			lower_ull  = -GET_CVALUE( int64, symbol->lower_limit);
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   223
			dimension  =  GET_CVALUE(uint64, symbol->upper_limit) + lower_ull;     
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   224
			if (dimension < lower_ull)
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   225
				STAGE3_ERROR(0, symbol, symbol, "Number of elements in array subrange exceeds maximum number of elements (%llu).", std::numeric_limits< unsigned long long int >::max());
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   226
		}
975
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   227
	} else if (!VALID_CVALUE(uint64, symbol->upper_limit) && !VALID_CVALUE( int64, symbol->upper_limit)) {
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   228
		STAGE3_ERROR(0, symbol->upper_limit, symbol->upper_limit, "Subrange upper limit is not a constant value.");
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   229
		// set dimension to largest possible value so we do not get any further related error messages.
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   230
		dimension = std::numeric_limits< unsigned long long int >::max() - 1; // -1 because it will be incremented at the end of this function!! 
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   231
	} else if (!VALID_CVALUE(uint64, symbol->lower_limit) && !VALID_CVALUE( int64, symbol->lower_limit)) {
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   232
		STAGE3_ERROR(0, symbol->lower_limit, symbol->lower_limit, "Subrange lower limit is not a constant value.");
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   233
		// set dimension to largest possible value so we do not get any further related error messages.
3604464aa80e Add checks for use of non constant value in subranges, and lower_limit > upper_limit.
mjsousa
parents: 970
diff changeset
   234
		dimension = std::numeric_limits< unsigned long long int >::max() - 1; // -1 because it will be incremented at the end of this function!! 
976
619a2b9f6edf Add comments.
mjsousa
parents: 975
diff changeset
   235
		/* NOTE: Note that both the "subrange *** limit is not a constant value" error messages are only necessary due to an extension
619a2b9f6edf Add comments.
mjsousa
parents: 975
diff changeset
   236
		 *       that matiec supports by allowing non-literals in subrange declarations (currently only subranges in array declarations).
619a2b9f6edf Add comments.
mjsousa
parents: 975
diff changeset
   237
		 *         e.g.:  array_var: ARRAY [1..max] of INT;   <--- illegal according to IEC 61131-1 due to the 'max' non literal
619a2b9f6edf Add comments.
mjsousa
parents: 975
diff changeset
   238
		 *       Matiec will allow the above syntax, as long as the 'max' variable can be determined to be constant throughout
619a2b9f6edf Add comments.
mjsousa
parents: 975
diff changeset
   239
		 *       the program execution at runtime (and not only constant when program initiates) - for example, a VAR CONSTANT
619a2b9f6edf Add comments.
mjsousa
parents: 975
diff changeset
   240
		 *       variable.
619a2b9f6edf Add comments.
mjsousa
parents: 975
diff changeset
   241
		 *       These two checks will verify if we were able to fold the variable into a constant value, or not.
619a2b9f6edf Add comments.
mjsousa
parents: 975
diff changeset
   242
		 */
970
0ede7ca157e2 Remove debugging code left in by mistake.
mjsousa
parents: 965
diff changeset
   243
	} else {ERROR;}
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   244
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   245
	/* correct value for dimension is actually ---> dimension = upper_limit - lower_limit + 1
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   246
	 * Up to now, we have only determined dimension = upper_limit - lower_limit
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   247
	 * We must first check whether this last increment will cause an overflow!
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   248
	 */
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   249
	if (dimension == std::numeric_limits< unsigned long long int >::max())
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   250
		STAGE3_ERROR(0, symbol, symbol, "Number of elements in array subrange exceeds maximum number of elements (%llu).", std::numeric_limits< unsigned long long int >::max());
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   251
	
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   252
	/* correct value for dimension is actually ---> dimension = upper_limit - lower_limit + 1 */
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   253
	dimension++; 
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   254
	
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   255
	symbol->dimension = dimension;
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   256
	return NULL;
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   257
}
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   258
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   259
598
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   260
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   261
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   262
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   263
/* integer '(' [array_initial_element] ')' */
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   264
/* array_initial_element may be NULL ! */
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   265
// SYM_REF2(array_initial_elements_c, integer, array_initial_element)
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   266
void *array_range_check_c::visit(array_initial_elements_c *symbol) {
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   267
	if (VALID_CVALUE( int64, symbol->integer) && (GET_CVALUE( int64, symbol->integer) < 0)) 
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   268
		ERROR; /* the IEC 61131-3 syntax guarantees that this value will never be negative! */
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   269
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   270
	/* TODO: check that the total number of 'initial values' does not exceed the size of the array! */
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   271
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   272
	return NULL;
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   273
}
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   274
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   275
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   276
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   277
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   278
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   279
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   280
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   281
0b1ee7e7123b Fix stupid typos (in calculating array dimension)!
Mario de Sousa <msousa@fe.up.pt>
parents: 594
diff changeset
   282
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   283
/*********************/
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   284
/* B 1.4 - Variables */
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   285
/*********************/
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   286
/*************************************/
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   287
/* B 1.4.2 - Multi-element variables */
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   288
/*************************************/
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   289
void *array_range_check_c::visit(array_variable_c *symbol) {
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   290
	check_dimension_count(symbol);
581
1e158dc9f9c1 Add check array out of bound.
Manuele Conti <conti.ma@alice.it>
parents: 560
diff changeset
   291
	check_bounds(symbol);
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   292
	return NULL;
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   293
}
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   294
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   295
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   296
/**************************************/
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   297
/* B 1.5 - Program organisation units */
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   298
/**************************************/
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   299
/***********************/
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   300
/* B 1.5.1 - Functions */
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   301
/***********************/
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   302
// SYM_REF4(function_declaration_c, derived_function_name, type_name, var_declarations_list, function_body)
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   303
void *array_range_check_c::visit(function_declaration_c *symbol) {
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   304
	symbol->var_declarations_list->accept(*this); // required for visiting subrange_c
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   305
	search_varfb_instance_type = new search_varfb_instance_type_c(symbol);
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   306
	// search_var_instance_decl = new search_var_instance_decl_c(symbol);
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   307
	symbol->function_body->accept(*this);
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   308
	delete search_varfb_instance_type;
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   309
	// delete search_var_instance_decl;
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   310
	search_varfb_instance_type = NULL;
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   311
	// search_var_instance_decl = NULL;
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   312
	return NULL;
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   313
}
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   314
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   315
/*****************************/
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   316
/* B 1.5.2 - Function blocks */
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   317
/*****************************/
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   318
// SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body)
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   319
void *array_range_check_c::visit(function_block_declaration_c *symbol) {
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   320
	symbol->var_declarations->accept(*this); // required for visiting subrange_c
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   321
	search_varfb_instance_type = new search_varfb_instance_type_c(symbol);
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   322
	// search_var_instance_decl = new search_var_instance_decl_c(symbol);
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   323
	symbol->fblock_body->accept(*this);
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   324
	delete search_varfb_instance_type;
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   325
	// delete search_var_instance_decl;
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   326
	search_varfb_instance_type = NULL;
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   327
	// search_var_instance_decl = NULL;
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   328
	return NULL;
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   329
}
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   330
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   331
/**********************/
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   332
/* B 1.5.3 - Programs */
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   333
/**********************/
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   334
// SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body)
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   335
void *array_range_check_c::visit(program_declaration_c *symbol) {
592
99a284cec1f2 Add 'dimension' parameter to subrange_c, fill it correctly, and use it.
Mario de Sousa <msousa@fe.up.pt>
parents: 585
diff changeset
   336
	symbol->var_declarations->accept(*this); // required for visiting subrange_c
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   337
	search_varfb_instance_type = new search_varfb_instance_type_c(symbol);
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   338
	// search_var_instance_decl = new search_var_instance_decl_c(symbol);
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   339
	symbol->function_block_body->accept(*this);
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   340
	delete search_varfb_instance_type;
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   341
	// delete search_var_instance_decl;
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   342
	search_varfb_instance_type = NULL;
560
13b5b7faa3d7 Renamed class, remove unused code, delete allocated objects.
mjsousa <msousa@fe.up.pt>
parents: 559
diff changeset
   343
	// search_var_instance_decl = NULL;
559
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   344
	return NULL;
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   345
}
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   346
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   347
a3b8925e640c Start sematinc range check class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   348