Skip to content

Commit

Permalink
refs #3409 added warnings for the [] operator for constant values tha…
Browse files Browse the repository at this point in the history
…t are not integers
  • Loading branch information
davidnich committed Jan 14, 2022
1 parent 9c8c01d commit 8d5ebfb
Show file tree
Hide file tree
Showing 8 changed files with 429 additions and 340 deletions.
2 changes: 2 additions & 0 deletions doxygen/lang/900_release_notes.dox.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
(<a href="https://github.com/qorelanguage/qore/issues/4382">issue 4382</a>)
- added regex APIs to the C++ string class
(<a href="https://github.com/qorelanguage/qore/issues/4379">issue 4379</a>)
- added a warning for constant operands with the square bracket operator that are not integers
(<a href="https://github.com/qorelanguage/qore/issues/3409">issue 3409</a>)

@section qore_1_0_13 Qore 1.0.13

Expand Down
10 changes: 9 additions & 1 deletion include/qore/QoreValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,18 @@ class QoreSimpleValue {
DLLEXPORT bool needsEval() const;

//! returns true if the value is a scalar (int, bool, float, number, string)
/** @%Qore 1.0
/** @since %Qore 1.0
*/
DLLEXPORT bool isScalar() const;

//! returns true if the value is a constant value (does not require evaluation)
/** returns true if the type is a constant int, bool, float, number, string, list, hash, date, binary, object,
nothing, or null value
@since %Qore 1.1
*/
DLLEXPORT bool isConstant() const;

//! returns true if the value is not NOTHING
DLLEXPORT operator bool() const;

Expand Down
5 changes: 5 additions & 0 deletions include/qore/intern/QoreLibIntern.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ struct QoreParseContext {
int pflag = 0;
int lvids = 0;
const QoreTypeInfo* typeInfo = nullptr;
qore_type_t value_type = -1;

DLLLOCAL QoreParseContext(QoreProgram* pgm = getProgram()) : pgm(pgm) {
}
Expand All @@ -170,6 +171,10 @@ struct QoreParseContext {
pflag |= flags;
return rv;
}

DLLLOCAL bool isConstant() const {
return value_type >= NT_NOTHING && value_type <= NT_NUMBER;
}
};

class QoreParseContextFlagHelper {
Expand Down
368 changes: 200 additions & 168 deletions lib/Pseudo_QC_String.qpp

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions lib/QoreLib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ bool qore_has_debug() {
}

int parse_init_value(QoreValue& val, QoreParseContext& parse_context) {
parse_context.value_type = val.getType();
if (val.hasNode()) {
AbstractQoreNode* n = val.getInternalNode();
//printd(5, "parse_init_value() n: %p '%s'\n", n, get_type_name(n));
Expand Down
39 changes: 31 additions & 8 deletions lib/QoreSquareBracketsOperatorNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,24 @@ int QoreSquareBracketsOperatorNode::parseInitImpl(QoreValue& val, QoreParseConte

// if the rhs cannot be a list, see if the rhs is a type that can be converted to an integer, if not raise an
// invalid operation warning
if (!rti_can_be_list && !QoreTypeInfo::canConvertToScalar(rti)) {
// FIXME: raise exceptions with %strict-types
QoreStringNode* edesc = new QoreStringNode("the offset operand expression with the '[]' operator is ");
QoreTypeInfo::getThisType(rti, *edesc);
edesc->concat(" and so will always evaluate to zero");
qore_program_private::makeParseWarning(getProgram(), *loc, QP_WARN_INVALID_OPERATION, "INVALID-OPERATION",
edesc);
if (!rti_can_be_list) {
if (!QoreTypeInfo::canConvertToScalar(rti)) {
// FIXME: raise exceptions with %strict-types
QoreStringNode* edesc = new QoreStringNode("the offset operand expression with the '[]' operator is ");
QoreTypeInfo::getThisType(rti, *edesc);
edesc->concat(" and so will always evaluate to zero");
qore_program_private::makeParseWarning(getProgram(), *loc, QP_WARN_INVALID_OPERATION, "INVALID-OPERATION",
edesc);
} else if (parse_context.isConstant() && parse_context.value_type != NT_INT) {
// FIXME: raise exceptions with %strict-types
QoreStringNode* edesc = new QoreStringNode("the offset operand expression with the '[]' operator is a "
"constant of ");
QoreTypeInfo::getThisType(rti, *edesc);
edesc->sprintf(" and will be automatically converted to an integer when evaluated; use a constant "
"integer operand instead");
qore_program_private::makeParseWarning(getProgram(), *loc, QP_WARN_INVALID_OPERATION, "INVALID-OPERATION",
edesc);
}
}

if (rti_is_list) {
Expand Down Expand Up @@ -206,8 +217,20 @@ int QoreSquareBracketsOperatorNode::parseCheckValueTypes(const QoreListNode* ln)
ConstListIterator i(ln);
int err = 0;
while (i.next()) {
const QoreTypeInfo* vti = i.getValue().getTypeInfo();
QoreValue v = i.getValue();
const QoreTypeInfo* vti = v.getTypeInfo();
if (QoreTypeInfo::canConvertToScalar(vti)) {
// check if we have a cosntant value that's not an int
if (v.isConstant() && v.getType() != NT_INT) {
// FIXME: raise exceptions with %strict-types
QoreStringNode* edesc = new QoreStringNodeMaker("the offset operand expression with the '[]' "
"operator in list element %d (starting with 1) is a constant of ", i.index() + 1);
QoreTypeInfo::getThisType(vti, *edesc);
edesc->sprintf(" and will be automatically converted to an integer when evaluated; use a constant "
"integer operand instead");
qore_program_private::makeParseWarning(getProgram(), *loc, QP_WARN_INVALID_OPERATION, "INVALID-OPERATION",
edesc);
}
continue;
}
parseException(*loc, "PARSE-TYPE-ERROR", "cannot make a slice with offset %lu/%lu of type '%s'; need a " \
Expand Down
5 changes: 5 additions & 0 deletions lib/QoreValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,11 @@ bool QoreSimpleValue::isValue() const {
return type != QV_Node || (v.n && v.n->is_value());
}

bool QoreSimpleValue::isConstant() const {
qore_type_t t = getType();
return t >= NT_NOTHING && t <= NT_NUMBER;
}

bool QoreSimpleValue::needsEval() const {
return type == QV_Node && v.n && v.n->needs_eval();
}
Expand Down
Loading

0 comments on commit 8d5ebfb

Please sign in to comment.