8214059: Undefined behaviour in ADLC

Mon, 11 Feb 2019 17:00:04 +0100

author
shade
date
Mon, 11 Feb 2019 17:00:04 +0100
changeset 9615
c5e1abd2d0af
parent 9614
bb44c0e88235
child 9616
faa71d8b8ab5

8214059: Undefined behaviour in ADLC
Reviewed-by: shade, kbarrett
Contributed-by: Simon Tooke <stooke@redhat.com>

src/share/vm/adlc/adlparse.cpp file | annotate | diff | comparison | revisions
src/share/vm/adlc/dfa.cpp file | annotate | diff | comparison | revisions
src/share/vm/adlc/formssel.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/adlc/adlparse.cpp	Wed Feb 06 11:41:51 2019 +0100
     1.2 +++ b/src/share/vm/adlc/adlparse.cpp	Mon Feb 11 17:00:04 2019 +0100
     1.3 @@ -2868,7 +2868,8 @@
     1.4    const char* param = NULL;
     1.5    inst._parameters.reset();
     1.6    while ((param = inst._parameters.iter()) != NULL) {
     1.7 -    OperandForm* opForm = (OperandForm*) inst._localNames[param];
     1.8 +    OpClassForm* opForm = inst._localNames[param]->is_opclass();
     1.9 +    assert(opForm != NULL, "sanity");
    1.10      encoding->add_parameter(opForm->_ident, param);
    1.11    }
    1.12  
    1.13 @@ -3338,7 +3339,8 @@
    1.14    const char* param = NULL;
    1.15    inst._parameters.reset();
    1.16    while ((param = inst._parameters.iter()) != NULL) {
    1.17 -    OperandForm* opForm = (OperandForm*) inst._localNames[param];
    1.18 +    OpClassForm* opForm = inst._localNames[param]->is_opclass();
    1.19 +    assert(opForm != NULL, "sanity");
    1.20      encoding->add_parameter(opForm->_ident, param);
    1.21    }
    1.22  
     2.1 --- a/src/share/vm/adlc/dfa.cpp	Wed Feb 06 11:41:51 2019 +0100
     2.2 +++ b/src/share/vm/adlc/dfa.cpp	Mon Feb 11 17:00:04 2019 +0100
     2.3 @@ -757,19 +757,27 @@
     2.4  }
     2.5  
     2.6  int Expr::compute_min(const Expr *c1, const Expr *c2) {
     2.7 -  int result = c1->_min_value + c2->_min_value;
     2.8 -  assert( result >= 0, "Invalid cost computation");
     2.9 +  int v1 = c1->_min_value;
    2.10 +  int v2 = c2->_min_value;
    2.11 +  assert(0 <= v2 && v2 <= Expr::Max, "sanity");
    2.12 +  assert(v1 <= Expr::Max - v2, "Invalid cost computation");
    2.13  
    2.14 -  return result;
    2.15 +  return v1 + v2;
    2.16  }
    2.17  
    2.18 +
    2.19  int Expr::compute_max(const Expr *c1, const Expr *c2) {
    2.20 -  int result = c1->_max_value + c2->_max_value;
    2.21 -  if( result < 0 ) {  // check for overflow
    2.22 -    result = Expr::Max;
    2.23 +  int v1 = c1->_max_value;
    2.24 +  int v2 = c2->_max_value;
    2.25 +
    2.26 +  // Check for overflow without producing UB. If v2 is positive
    2.27 +  // and not larger than Max, the subtraction cannot underflow.
    2.28 +  assert(0 <= v2 && v2 <= Expr::Max, "sanity");
    2.29 +  if (v1 > Expr::Max - v2) {
    2.30 +    return Expr::Max;
    2.31    }
    2.32  
    2.33 -  return result;
    2.34 +  return v1 + v2;
    2.35  }
    2.36  
    2.37  void Expr::print() const {
     3.1 --- a/src/share/vm/adlc/formssel.cpp	Wed Feb 06 11:41:51 2019 +0100
     3.2 +++ b/src/share/vm/adlc/formssel.cpp	Mon Feb 11 17:00:04 2019 +0100
     3.3 @@ -921,7 +921,8 @@
     3.4    const char *name;
     3.5    const char *kill_name = NULL;
     3.6    for (_parameters.reset(); (name = _parameters.iter()) != NULL;) {
     3.7 -    OperandForm *opForm = (OperandForm*)_localNames[name];
     3.8 +    OpClassForm *opForm = _localNames[name]->is_opclass();
     3.9 +    assert(opForm != NULL, "sanity");
    3.10  
    3.11      Effect* e = NULL;
    3.12      {
    3.13 @@ -938,7 +939,8 @@
    3.14        // complex so simply enforce the restriction during parse.
    3.15        if (kill_name != NULL &&
    3.16            e->isa(Component::TEMP) && !e->isa(Component::DEF)) {
    3.17 -        OperandForm* kill = (OperandForm*)_localNames[kill_name];
    3.18 +        OpClassForm* kill = _localNames[kill_name]->is_opclass();
    3.19 +        assert(kill != NULL, "sanity");
    3.20          globalAD->syntax_err(_linenum, "%s: %s %s must be at the end of the argument list\n",
    3.21                               _ident, kill->_ident, kill_name);
    3.22        } else if (e->isa(Component::KILL) && !e->isa(Component::USE)) {
    3.23 @@ -2339,7 +2341,8 @@
    3.24    // Add parameters that "do not appear in match rule".
    3.25    const char *name;
    3.26    for (_parameters.reset(); (name = _parameters.iter()) != NULL;) {
    3.27 -    OperandForm *opForm = (OperandForm*)_localNames[name];
    3.28 +    OpClassForm *opForm = _localNames[name]->is_opclass();
    3.29 +    assert(opForm != NULL, "sanity");
    3.30  
    3.31      if ( _components.operand_position(name) == -1 ) {
    3.32        _components.insert(name, opForm->_ident, Component::INVALID, false);

mercurial