stage3/array_range_check.cc
author mjsousa
Sat, 07 May 2016 21:17:49 +0100
changeset 1010 242907849850
parent 977 4612cf723c6a
child 1041 56ebe2a31b5b
permissions -rw-r--r--
Correctly identify errors when parsing erroneous code (make sure flex goes back to INITIAL state when code contains errors that do not allow determining whether ST or IL is being parsed)
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 */
583
e1df3781be84 Fix array index bound check to consider uint64 indexes/limits.
Mario de Sousa <msousa@fe.up.pt>
parents: 581
diff changeset
   136
    if ( VALID_CVALUE( int64, l->elements[i]) && VALID_CVALUE( int64, dimension->lower_limit))
620
aef32856eeb5 Remove warning about comparisons between int and unsigned int.
Manuele Conti <conti.ma@alice.it>
parents: 614
diff changeset
   137
      if ( GET_CVALUE( int64, l->elements[i]) < GET_CVALUE( int64, dimension->lower_limit) )
977
4612cf723c6a Make error message more informative.
mjsousa
parents: 976
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->elements[i]), GET_CVALUE( int64, dimension->lower_limit)); continue;}
581
1e158dc9f9c1 Add check array out of bound.
Manuele Conti <conti.ma@alice.it>
parents: 560
diff changeset
   139
599
60f3edcf6a8f fix array bounds check.
Mario de Sousa <msousa@fe.up.pt>
parents: 598
diff changeset
   140
    if ( VALID_CVALUE( int64, l->elements[i]) && VALID_CVALUE(uint64, dimension->lower_limit))
620
aef32856eeb5 Remove warning about comparisons between int and unsigned int.
Manuele Conti <conti.ma@alice.it>
parents: 614
diff changeset
   141
      if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->lower_limit), GET_CVALUE( int64, l->elements[i])) > 0 )
977
4612cf723c6a Make error message more informative.
mjsousa
parents: 976
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->elements[i]), GET_CVALUE(uint64, dimension->lower_limit)); continue;}
599
60f3edcf6a8f fix array bounds check.
Mario de Sousa <msousa@fe.up.pt>
parents: 598
diff changeset
   143
60f3edcf6a8f fix array bounds check.
Mario de Sousa <msousa@fe.up.pt>
parents: 598
diff changeset
   144
    if ( VALID_CVALUE(uint64, l->elements[i]) && VALID_CVALUE(uint64, dimension->lower_limit))
60f3edcf6a8f fix array bounds check.
Mario de Sousa <msousa@fe.up.pt>
parents: 598
diff changeset
   145
      if ( GET_CVALUE(uint64, l->elements[i])   <  GET_CVALUE(uint64, dimension->lower_limit))
977
4612cf723c6a Make error message more informative.
mjsousa
parents: 976
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->elements[i]), GET_CVALUE(uint64, dimension->lower_limit)); continue;}
599
60f3edcf6a8f fix array bounds check.
Mario de Sousa <msousa@fe.up.pt>
parents: 598
diff changeset
   147
60f3edcf6a8f fix array bounds check.
Mario de Sousa <msousa@fe.up.pt>
parents: 598
diff changeset
   148
    if ( VALID_CVALUE(uint64, l->elements[i]) && VALID_CVALUE( int64, dimension->lower_limit))
620
aef32856eeb5 Remove warning about comparisons between int and unsigned int.
Manuele Conti <conti.ma@alice.it>
parents: 614
diff changeset
   149
      if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->elements[i]), GET_CVALUE( int64, dimension->lower_limit)) < 0 )
977
4612cf723c6a Make error message more informative.
mjsousa
parents: 976
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->elements[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 */
583
e1df3781be84 Fix array index bound check to consider uint64 indexes/limits.
Mario de Sousa <msousa@fe.up.pt>
parents: 581
diff changeset
   153
    if ( VALID_CVALUE( int64, l->elements[i]) && VALID_CVALUE( int64, dimension->upper_limit))
e1df3781be84 Fix array index bound check to consider uint64 indexes/limits.
Mario de Sousa <msousa@fe.up.pt>
parents: 581
diff changeset
   154
      if ( GET_CVALUE( int64, l->elements[i])   >  GET_CVALUE( int64, dimension->upper_limit))
977
4612cf723c6a Make error message more informative.
mjsousa
parents: 976
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->elements[i]), GET_CVALUE( int64, dimension->upper_limit)); continue;}
583
e1df3781be84 Fix array index bound check to consider uint64 indexes/limits.
Mario de Sousa <msousa@fe.up.pt>
parents: 581
diff changeset
   156
599
60f3edcf6a8f fix array bounds check.
Mario de Sousa <msousa@fe.up.pt>
parents: 598
diff changeset
   157
    if ( VALID_CVALUE( int64, l->elements[i]) && VALID_CVALUE(uint64, dimension->upper_limit))
620
aef32856eeb5 Remove warning about comparisons between int and unsigned int.
Manuele Conti <conti.ma@alice.it>
parents: 614
diff changeset
   158
      if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->upper_limit), GET_CVALUE( int64, l->elements[i])) < 0 )
977
4612cf723c6a Make error message more informative.
mjsousa
parents: 976
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->elements[i]), GET_CVALUE(uint64, dimension->upper_limit)); continue;}
583
e1df3781be84 Fix array index bound check to consider uint64 indexes/limits.
Mario de Sousa <msousa@fe.up.pt>
parents: 581
diff changeset
   160
e1df3781be84 Fix array index bound check to consider uint64 indexes/limits.
Mario de Sousa <msousa@fe.up.pt>
parents: 581
diff changeset
   161
    if ( VALID_CVALUE(uint64, l->elements[i]) && VALID_CVALUE(uint64, dimension->upper_limit))
e1df3781be84 Fix array index bound check to consider uint64 indexes/limits.
Mario de Sousa <msousa@fe.up.pt>
parents: 581
diff changeset
   162
      if ( GET_CVALUE(uint64, l->elements[i])   >  GET_CVALUE(uint64, dimension->upper_limit))
977
4612cf723c6a Make error message more informative.
mjsousa
parents: 976
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->elements[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
      
599
60f3edcf6a8f fix array bounds check.
Mario de Sousa <msousa@fe.up.pt>
parents: 598
diff changeset
   165
    if ( VALID_CVALUE(uint64, l->elements[i]) && VALID_CVALUE( int64, dimension->upper_limit))
625
c0bda77b37a0 Merge with c2546c6e0cfa5ad55b288895f17f1b9f2a228f3b
Laurent Bessard
parents: 621
diff changeset
   166
      if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->elements[i]), GET_CVALUE( int64, dimension->upper_limit)) > 0 )
977
4612cf723c6a Make error message more informative.
mjsousa
parents: 976
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->elements[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