diff --git a/final_walk.cc b/final_walk.cc index 8e019bc..689061e 100644 --- a/final_walk.cc +++ b/final_walk.cc @@ -120,6 +120,27 @@ void LLScriptListConstant::final_pre_checks() { } } +void LLScriptTypecastExpression::final_pre_checks() { + if (!mono_mode && get_type()->get_itype() == LST_LIST) { + // Check if it only has a variable of type string or key + LLASTNode *child = get_children(); + if (child && !child->get_next() && child->get_node_type() == NODE_EXPRESSION && child->get_node_sub_type() == NODE_LVALUE_EXPRESSION) { + // We're on the right track. Go one level deeper. + child = child->get_children(); + if (child && !child->get_next() && child->get_node_type() == NODE_IDENTIFIER) { + LST_TYPE type = child->get_type()->get_itype(); + // A-ha! + if (type == LST_STRING) { + ERROR(HERE, W_LSO_LIST_TO_KEY_OR_STR, "string", "key", "string"); + } else if (type == LST_KEY) { + ERROR(HERE, W_LSO_LIST_TO_KEY_OR_STR, "key", "string", "key"); + } + } + } + + } +} + void LLScriptIfStatement::final_pre_checks() { check_cond((LLScriptExpression*)get_child(0), true); } diff --git a/logger.cc b/logger.cc index 484e0ce..1d1a4a5 100644 --- a/logger.cc +++ b/logger.cc @@ -317,4 +317,6 @@ const char *Logger::warning_messages[] = { "Prefixing a string with L will cause a double quote (\")\n" "to be inserted at the beginning of the string.", // 20019 "print does nothing. Attempting to use the result %s.\n", // 20020 + "In LSO, (list)%s_var can result in a variable of type %s in the list." + " Use [%s_var] instead.", // 20021 }; diff --git a/logger.hh b/logger.hh index 4217422..6ae8dd2 100644 --- a/logger.hh +++ b/logger.hh @@ -113,6 +113,7 @@ enum ErrorCode { W_DUPLICATE_CASE, // 20018 W_L_STRING, // 20019 W_PRINT, // 20020 + W_LSO_LIST_TO_KEY_OR_STR, // 20021 W_LAST }; diff --git a/lslmini.hh b/lslmini.hh index f15251b..17cda70 100644 --- a/lslmini.hh +++ b/lslmini.hh @@ -547,6 +547,7 @@ class LLScriptTypecastExpression : public LLScriptExpression { virtual void determine_type() {}; // type already determined virtual const char *get_node_name() { return "typecast expression"; } virtual LLNodeSubType get_node_sub_type() { return NODE_TYPECAST_EXPRESSION; }; + virtual void final_pre_checks(); }; class LLScriptFunctionExpression : public LLScriptExpression { diff --git a/scripts/lso/liststrkey.lsl b/scripts/lso/liststrkey.lsl new file mode 100644 index 0000000..f2f407d --- /dev/null +++ b/scripts/lso/liststrkey.lsl @@ -0,0 +1,22 @@ +default +{ + state_entry() + { + key k = llGetObjectName(); + string s = llGetKey(); + + list ls = + (list) // $[E20021] could result in a string + k; + ls = ls + + (list) // $[E20021] could result in a key + s; + + if (llGetListEntryType(ls, 0) == TYPE_STRING + && llGetListEntryType(ls, 1) == TYPE_KEY) + { + // This is printed! + llOwnerSay("LSO has weird bugs"); + } + } +} diff --git a/scripts/mono/liststrkey.lsl b/scripts/mono/liststrkey.lsl new file mode 100644 index 0000000..2fde89d --- /dev/null +++ b/scripts/mono/liststrkey.lsl @@ -0,0 +1,18 @@ +default +{ + state_entry() + { + key k = llGetObjectName(); + string s = llGetKey(); + + list ls = (list)k; // no E20021 in mono + ls = ls + (list)s; // no E20021 in mono + + if (llGetListEntryType(ls, 0) != TYPE_STRING + && llGetListEntryType(ls, 1) != TYPE_KEY) + { + // Not printed in Mono + llOwnerSay("Mono is safe"); + } + } +}