Add check whether the same constant var_external variable is initialised with two (or more) different constant values.
authormjsousa
Tue, 30 Dec 2014 22:58:52 +0000
changeset 983 ead554e12195
parent 982 760b26477193
child 984 634269b0f104
Add check whether the same constant var_external variable is initialised with two (or more) different constant values.
absyntax/absyntax.hh
stage3/constant_folding.cc
--- a/absyntax/absyntax.hh	Tue Dec 30 22:17:22 2014 +0000
+++ b/absyntax/absyntax.hh	Tue Dec 30 22:58:52 2014 +0000
@@ -127,6 +127,13 @@
       bool       is_nonconst (void)     {return (status == cs_non_const  );}
       bool       is_undefined(void)     {return (status == cs_undefined  );}
       bool       is_zero     (void)     {return (is_valid() && (get() == 0));}
+
+      /* comparison operator */
+      bool operator==(const const_value__ cv) {
+        return (    ((status!=cs_const_value) && (status==cv.status)) 
+                 || ((status==cs_const_value) && (value ==cv.value )));
+      }
+
     };
 
     const_value__< int64_t>  _int64; /* status is initialised to UNDEFINED */
@@ -137,6 +144,10 @@
     /* default constructor and destructor */
      const_value_c(void) {};
     ~const_value_c(void) {};
+    
+    /* comparison operator */
+    bool operator==(const const_value_c cv)
+      {return ((_int64==cv._int64) && (_uint64==cv._uint64) && (_real64==cv._real64) && (_bool==cv._bool));}                                                     
 };
 
 
--- a/stage3/constant_folding.cc	Tue Dec 30 22:17:22 2014 +0000
+++ b/stage3/constant_folding.cc	Tue Dec 30 22:58:52 2014 +0000
@@ -194,6 +194,7 @@
 #define VALID_CVALUE(dtype, symbol)           ((symbol)->const_value._##dtype.is_valid())
 #define IS_OVFLOW(dtype, symbol)              ((symbol)->const_value._##dtype.is_overflow())
 #define IS_NONCONST(dtype, symbol)            ((symbol)->const_value._##dtype.is_nonconst())
+#define IS_UNDEFINED(dtype, symbol)           ((symbol)->const_value._##dtype.is_undefined())
 #define ISZERO_CVALUE(dtype, symbol)          ((symbol)->const_value._##dtype.is_zero())
 
 
@@ -1254,8 +1255,29 @@
   /* However, we only do this is if the visit() method for the Program/FB in which this VAR_EXTERN is found was called from the visit(configurtion/resource) visitor!
    * When we are called from the visit(library_c) visitor, we do not have the required information to do this!
    */ 
-  if (NULL != current_configuration)
+  if (NULL != current_configuration) {
+    /* before copying the constant value from the VAR_GLOBAL declaration (which is stored in the var_global_values[] map)
+     * we check to see if the VAR_EXTERN constant values has already been set by a previous call to constant fold the POU
+     * in which this VAR_EXTERN is found we simply check to see if any const value of this VAR_EXTERN variable has already
+     * been set previously!
+     */
+    if (   !IS_UNDEFINED( int64, symbol->specification) || !IS_UNDEFINED(uint64, symbol->specification) 
+        || !IS_UNDEFINED(real64, symbol->specification) || !IS_UNDEFINED(  bool, symbol->specification)) {
+      /* The const_value for this VAR_EXTERN has already been previously set. Lets check to see if it is the exact
+       * same const value - if not we produce an error message!
+       * 
+       * NOTE: comparison is inverted with '!'
+       */
+      if (! (symbol->specification->const_value == var_global_values[get_var_name_c::get_name(symbol->global_var_name)->value]))
+        STAGE3_ERROR(0, symbol, symbol, "The initial value of this external variable is ambiguous (the Program/FB in which "
+                                        "this external variable is declared has been used to instantiate a Program/FB in more "
+                                        "than one configuration and/or resource - and each resource sets the corresponding global "
+                                        "variable to a distinct constant initial value).");
+    }
+    
+    // only now do we copy the const value from the var_global to the var_external.
     symbol->specification->const_value = var_global_values[get_var_name_c::get_name(symbol->global_var_name)->value];
+  }
   
   symbol->global_var_name->const_value = symbol->specification->const_value;
   if (fixed_init_value_) {