diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index 300aea817..1e06fd10c 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -4524,6 +4524,7 @@ public: void isImplicit(bool flag) { m_isImplicit = flag; } bool isScoped() const { return m_isScoped; } void isScoped(bool flag) { m_isScoped = flag; } + bool isPure() override { return false; } }; class AstTaskRef final : public AstNodeFTaskRef { // A reference to a task diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 9b5ba8996..2afc17493 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -3241,10 +3241,16 @@ class ConstVisitor final : public VNVisitor { } else if (!AstNode::afterCommentp(nodep->thensp()) && !AstNode::afterCommentp(nodep->elsesp())) { if (!nodep->condp()->isPure()) { - // Condition has side effect - leave - perhaps in - // future simplify to remove all but side effect terms + // Condition has side effect - leave, but don't need return value + UINFO(4, "IF({x}) ; => STMTEXPR({x}): " << nodep); + nodep->fileline()->warnOff(V3ErrorCode::IGNOREDRETURN, true); + AstNodeStmt* const newp + = new AstStmtExpr{nodep->fileline(), nodep->condp()->unlinkFrBack()}; + nodep->replaceWith(newp); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } else { // Empty block, remove it + UINFO(4, "IF({x}) ; => ; : " << nodep); VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); } } else if (!AstNode::afterCommentp(nodep->thensp())) { @@ -3498,6 +3504,8 @@ class ConstVisitor final : public VNVisitor { } // TODO if there's an ExprStmt underneath just keep lower statements // (No current test case needs this) + // TODO if non-pure, can remove keep removing upper pure-itself + // NodeUniOp/NodeBiOp until get to the non-pure child-node expression } // Simplify diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index ecf20d1d4..26fb1932d 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -241,7 +241,8 @@ class RandomizeMarkVisitor final : public VNVisitor { methodHardp->v3fatalSrc("Unknown rand_mode() receiver"); } } - if (!nodep->pinsp() && VN_IS(nodep->backp(), StmtExpr)) { + if (!nodep->pinsp() && VN_IS(nodep->backp(), StmtExpr) + && !nodep->backp()->fileline()->warnIsOff(V3ErrorCode::IGNOREDRETURN)) { nodep->v3warn( IGNOREDRETURN, "Ignoring return value of non-void function (IEEE 1800-2023 13.4.1)"); @@ -302,7 +303,8 @@ class RandomizeMarkVisitor final : public VNVisitor { nodep->v3error( "'constraint_mode()' with arguments cannot be called as a function"); valid = false; - } else if (!nodep->pinsp() && VN_IS(nodep->backp(), StmtExpr)) { + } else if (!nodep->pinsp() && VN_IS(nodep->backp(), StmtExpr) + && !nodep->backp()->fileline()->warnIsOff(V3ErrorCode::IGNOREDRETURN)) { nodep->v3warn( IGNOREDRETURN, "Ignoring return value of non-void function (IEEE 1800-2023 13.4.1)"); diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 358811654..b9a00f833 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -1510,7 +1510,8 @@ class TaskVisitor final : public VNVisitor { VIsCached::clearCacheTree(); } else { // VN_IS(nodep->backp(), StmtExpr) insertBeforeStmt(nodep, beginp); - if (nodep->taskp()->isFunction()) { + if (nodep->taskp()->isFunction() + && !nodep->backp()->fileline()->warnIsOff(V3ErrorCode::IGNOREDRETURN)) { nodep->v3warn( IGNOREDRETURN, "Ignoring return value of non-void function (IEEE 1800-2023 13.4.1)"); diff --git a/test_regress/t/t_class_dyn_cast_empty_if.v b/test_regress/t/t_class_dyn_cast_empty_if.v index f11e35bd4..42a02fc02 100644 --- a/test_regress/t/t_class_dyn_cast_empty_if.v +++ b/test_regress/t/t_class_dyn_cast_empty_if.v @@ -7,7 +7,7 @@ typedef class Derived; class Base; function Derived cast(); - if ($cast(cast,this)) begin end + if (!$cast(cast, this)) begin end endfunction endclass