Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bf7daf0

Browse files
author
Lu Guanqun
committed
[cond-expr] don't allow conditional as left value for the first stage
1 parent b003290 commit bf7daf0

File tree

3 files changed

+29
-61
lines changed

3 files changed

+29
-61
lines changed

libsolidity/analysis/TypeChecker.cpp

Lines changed: 25 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -748,55 +748,37 @@ bool TypeChecker::visit(Conditional const& _conditional)
748748
{
749749
expectType(_conditional.condition(), BoolType());
750750

751-
if (_conditional.annotation().lValueRequested)
752-
{
753-
requireLValue(_conditional.trueExpression());
754-
requireLValue(_conditional.falseExpression());
755-
756-
TypePointer const& trueType = type(_conditional.trueExpression());
757-
TypePointer const& falseType = type(_conditional.falseExpression());
751+
_conditional.trueExpression().accept(*this);
752+
_conditional.falseExpression().accept(*this);
758753

759-
// as a left value, we require exact match to prevent subtle conversion issues.
760-
if (*trueType != *falseType)
761-
typeError(
762-
_conditional.location(),
763-
"True expression's type " +
764-
trueType->toString() +
765-
" doesn't match false expression's type " +
766-
falseType->toString() +
767-
"."
768-
);
754+
TypePointer const& trueType = type(_conditional.trueExpression());
755+
TypePointer const& falseType = type(_conditional.falseExpression());
769756

770-
_conditional.annotation().type = trueType;
771-
_conditional.annotation().isLValue = true;
772-
}
773-
else
757+
// we fake it as an equal operator, but any other comparison operator can work.
758+
TypePointer commonType = trueType->binaryOperatorResult(Token::Equal, falseType);
759+
if (!commonType)
774760
{
775-
_conditional.trueExpression().accept(*this);
776-
_conditional.falseExpression().accept(*this);
761+
typeError(
762+
_conditional.location(),
763+
"True expression's type " +
764+
trueType->toString() +
765+
" doesn't match false expression's type " +
766+
falseType->toString() +
767+
"."
768+
);
769+
// even we can't find a common type, we have to set a type here,
770+
// otherwise the upper statement will not be able to check the type.
771+
commonType = trueType;
772+
}
777773

778-
TypePointer const& trueType = type(_conditional.trueExpression());
779-
TypePointer const& falseType = type(_conditional.falseExpression());
774+
_conditional.annotation().type = commonType;
780775

781-
// we fake it as an equal operator, but any other comparison operator can work.
782-
TypePointer commonType = trueType->binaryOperatorResult(Token::Equal, falseType);
783-
if (!commonType)
784-
{
785-
typeError(
786-
_conditional.location(),
787-
"True expression's type " +
788-
trueType->toString() +
789-
" doesn't match false expression's type " +
790-
falseType->toString() +
791-
"."
792-
);
793-
// even we can't find a common type, we have to set a type here,
794-
// otherwise the upper statement will not be able to check the type.
795-
commonType = trueType;
796-
}
776+
if (_conditional.annotation().lValueRequested)
777+
typeError(
778+
_conditional.location(),
779+
"Conditional expression as left value is not supported yet."
780+
);
797781

798-
_conditional.annotation().type = commonType;
799-
}
800782
return false;
801783
}
802784

test/libsolidity/SolidityEndToEndTest.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -128,22 +128,6 @@ BOOST_AUTO_TEST_CASE(conditional_expression_multiple)
128128
BOOST_CHECK(callContractFunction("f(uint256)", u256(40)) == toBigEndian(u256(10)));
129129
}
130130

131-
BOOST_AUTO_TEST_CASE(conditional_expression_as_left_value)
132-
{
133-
char const* sourceCode = R"(
134-
contract test {
135-
function f(uint x) returns(uint d) {
136-
uint y = 1;
137-
uint z = 1;
138-
(x > 10 ? y : z) = 3;
139-
return y ** z;
140-
}
141-
})";
142-
compileAndRun(sourceCode);
143-
BOOST_CHECK(callContractFunction("f(uint256)", u256(20)) == toBigEndian(u256(3)));
144-
BOOST_CHECK(callContractFunction("f(uint256)", u256(5)) == toBigEndian(u256(1)));
145-
}
146-
147131
BOOST_AUTO_TEST_CASE(conditional_expression_with_return_values)
148132
{
149133
char const* sourceCode = R"(

test/libsolidity/SolidityNameAndTypeResolution.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,12 +2972,14 @@ BOOST_AUTO_TEST_CASE(invalid_different_types_for_conditional_expression)
29722972
BOOST_CHECK(expectError(text) == Error::Type::TypeError);
29732973
}
29742974

2975-
BOOST_AUTO_TEST_CASE(invalid_left_value_in_conditional_expression)
2975+
BOOST_AUTO_TEST_CASE(left_value_in_conditional_expression_not_supported_yet)
29762976
{
29772977
char const* text = R"(
29782978
contract C {
29792979
function f() {
2980-
(true ? 3 : 5) = 1;
2980+
uint x;
2981+
uint y;
2982+
(true ? x : y) = 1;
29812983
}
29822984
}
29832985
)";

0 commit comments

Comments
 (0)