From a63a62bc4fbe55ac8c5b7a4c4dc4398a5f25c58f Mon Sep 17 00:00:00 2001 From: Alena Laskavaia Date: Sun, 1 May 2011 21:14:42 +0000 Subject: [PATCH] Bug 343767 - [fp] 'No return' warning when return in both if and else --- .../model/cfg/ControlFlowGraphBuilder.java | 33 ++++++++++++++++--- .../internal/checkers/ReturnCheckerTest.java | 10 ++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java index c5f9bd9d847..22076c92a50 100644 --- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java @@ -77,14 +77,14 @@ public class ControlFlowGraphBuilder { exits = new ArrayList(); dead = new ArrayList(); IBasicBlock last = createSubGraph(start, body); - if (!(last instanceof IExitNode)) { - returnExit = (CxxExitNode) factory.createExitNode(null); + if (!(last instanceof IExitNode) && !deadConnector(last)) { + returnExit = factory.createExitNode(null); returnExit.setStartNode(start); addOutgoing(last, returnExit); exits.add(returnExit); if (dead.size() > 0) { - for (Iterator iterator = dead.iterator(); iterator.hasNext();) { - IBasicBlock ds = (IBasicBlock) iterator.next(); + for (Iterator iterator = dead.iterator(); iterator.hasNext();) { + IBasicBlock ds = iterator.next(); IBasicBlock dl = findLast(ds); if (dl != null && dl.getOutgoingSize() == 0 && dl != returnExit) { ((AbstractBasicBlock) dl).addOutgoing(returnExit); @@ -97,6 +97,31 @@ public class ControlFlowGraphBuilder { return graph; } + /** + * @param last + * @return + */ + private boolean deadConnector(IBasicBlock conn) { + if (conn instanceof IJumpNode || conn instanceof IConnectorNode) { + if (conn.getIncomingSize() == 0) { + return true; + } + if (conn instanceof IJumpNode) { + IJumpNode jm = (IJumpNode) conn; + if (jm.isBackwardArc()) + return false; + } + IBasicBlock[] conns = conn.getIncomingNodes(); + for (int i = 0; i < conns.length; i++) { + IBasicBlock bb = conns[i]; + if (!deadConnector(bb)) + return false; + } + return true; + } + return false; + } + public IBasicBlock findLast(IBasicBlock node) { if (node instanceof IJumpNode) return null; diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java index d9174dd00eb..9169ac64a96 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java @@ -245,4 +245,14 @@ public class ReturnCheckerTest extends CheckerTestCase { loadCodeAndRunCpp(getAboveComment()); checkNoErrors(); } + //int bar(int foo) + //{ + // while(foo) { + // return 0; + // } + //} + public void testWhile() { + loadCodeAndRunCpp(getAboveComment()); + checkErrorLine(1); + } } \ No newline at end of file