Mercurial > hg > release > icedtea7-forest-2.6 > hotspot
changeset 6686:3e633517a887
8214059, PR3701: Undefined behaviour in ADLC
Reviewed-by: shade, kbarrett
Contributed-by: Simon Tooke <stooke@redhat.com>
author | sgehwolf |
---|---|
date | Mon, 11 Feb 2019 15:43:26 +0000 |
parents | 788bd17d1876 |
children | a90b5cc4e1d2 |
files | src/share/vm/adlc/adlparse.cpp src/share/vm/adlc/dfa.cpp src/share/vm/adlc/formssel.cpp |
diffstat | 3 files changed, 25 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/vm/adlc/adlparse.cpp Mon Feb 18 04:18:37 2019 +0000 +++ b/src/share/vm/adlc/adlparse.cpp Mon Feb 11 15:43:26 2019 +0000 @@ -2778,7 +2778,8 @@ const char* param = NULL; inst._parameters.reset(); while ((param = inst._parameters.iter()) != NULL) { - OperandForm* opForm = (OperandForm*) inst._localNames[param]; + OpClassForm* opForm = inst._localNames[param]->is_opclass(); + assert(opForm != NULL, "sanity"); encoding->add_parameter(opForm->_ident, param); } @@ -3218,7 +3219,8 @@ const char* param = NULL; inst._parameters.reset(); while ((param = inst._parameters.iter()) != NULL) { - OperandForm* opForm = (OperandForm*) inst._localNames[param]; + OpClassForm* opForm = inst._localNames[param]->is_opclass(); + assert(opForm != NULL, "sanity"); encoding->add_parameter(opForm->_ident, param); }
--- a/src/share/vm/adlc/dfa.cpp Mon Feb 18 04:18:37 2019 +0000 +++ b/src/share/vm/adlc/dfa.cpp Mon Feb 11 15:43:26 2019 +0000 @@ -757,19 +757,27 @@ } int Expr::compute_min(const Expr *c1, const Expr *c2) { - int result = c1->_min_value + c2->_min_value; - assert( result >= 0, "Invalid cost computation"); + int v1 = c1->_min_value; + int v2 = c2->_min_value; + assert(0 <= v2 && v2 <= Expr::Max, "sanity"); + assert(v1 <= Expr::Max - v2, "Invalid cost computation"); - return result; + return v1 + v2; } + int Expr::compute_max(const Expr *c1, const Expr *c2) { - int result = c1->_max_value + c2->_max_value; - if( result < 0 ) { // check for overflow - result = Expr::Max; + int v1 = c1->_max_value; + int v2 = c2->_max_value; + + // Check for overflow without producing UB. If v2 is positive + // and not larger than Max, the subtraction cannot underflow. + assert(0 <= v2 && v2 <= Expr::Max, "sanity"); + if (v1 > Expr::Max - v2) { + return Expr::Max; } - return result; + return v1 + v2; } void Expr::print() const {
--- a/src/share/vm/adlc/formssel.cpp Mon Feb 18 04:18:37 2019 +0000 +++ b/src/share/vm/adlc/formssel.cpp Mon Feb 11 15:43:26 2019 +0000 @@ -924,7 +924,8 @@ const char *name; const char *kill_name = NULL; for (_parameters.reset(); (name = _parameters.iter()) != NULL;) { - OperandForm *opForm = (OperandForm*)_localNames[name]; + OpClassForm *opForm = _localNames[name]->is_opclass(); + assert(opForm != NULL, "sanity"); Effect* e = NULL; { @@ -941,7 +942,8 @@ // complex so simply enforce the restriction during parse. if (kill_name != NULL && e->isa(Component::TEMP) && !e->isa(Component::DEF)) { - OperandForm* kill = (OperandForm*)_localNames[kill_name]; + OpClassForm* kill = _localNames[kill_name]->is_opclass(); + assert(kill != NULL, "sanity"); globalAD->syntax_err(_linenum, "%s: %s %s must be at the end of the argument list\n", _ident, kill->_ident, kill_name); } else if (e->isa(Component::KILL) && !e->isa(Component::USE)) { @@ -2334,7 +2336,8 @@ // Add parameters that "do not appear in match rule". const char *name; for (_parameters.reset(); (name = _parameters.iter()) != NULL;) { - OperandForm *opForm = (OperandForm*)_localNames[name]; + OpClassForm *opForm = _localNames[name]->is_opclass(); + assert(opForm != NULL, "sanity"); if ( _components.operand_position(name) == -1 ) { _components.insert(name, opForm->_ident, Component::INVALID, false);