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