Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'codan/org.eclipse.cdt.codan.core.tests/src/org')
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java677
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/cxx/CxxAstUtilsTest.java136
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/cxx/externaltool/ArgsSeparatorTest.java52
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/AbstractClassInstantiationCheckerTest.java376
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentInConditionCheckerTest.java143
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentToItselfCheckerTest.java81
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CaseBreakCheckerTest.java580
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CatchByReferenceTest.java139
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java650
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CommentCheckerLineTests.java81
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CommentCheckerNestedTests.java51
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/FormatStringCheckerTest.java266
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/NonVirtualDestructorCheckerTest.java221
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/ProblemBindingCheckerTest.java112
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java451
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnStyleCheckerTest.java114
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/StatementHasNoEffectCheckerTest.java197
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/SuggestedParenthesisCheckerTest.java77
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/SuspiciousSemicolonCheckerTest.java175
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/UnusedSymbolInFileScopeCheckerTest.java344
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/param/BasicProblemPreferenceTest.java131
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/param/ListProblemPreferenceTest.java132
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/param/MapProblemPreferenceTest.java92
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/AutomatedIntegrationSuite.java87
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CheckerTestCase.java261
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanCoreTestActivator.java63
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanFastCxxAstTestCase.java186
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanFastTestSuite.java49
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanTestCase.java274
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/TestUtils.java72
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/AssignmentInConditionQuickFixTest.java32
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/CaseBreakQuickFixTest.java69
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/CatchByReferenceQuickFixTest.java92
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/CreateLocalVariableQuickFixTest.java101
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/QuickFixTestCase.java150
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/SuggestedParenthesisQuickFixTest.java65
36 files changed, 6779 insertions, 0 deletions
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java
new file mode 100644
index 00000000000..b9cfd4d9426
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java
@@ -0,0 +1,677 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2015 Alena Laskavaia
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alena Laskavaia - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.cfg;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.eclipse.cdt.codan.core.cxx.internal.model.cfg.ControlFlowGraphBuilder;
+import org.eclipse.cdt.codan.core.model.IChecker;
+import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock;
+import org.eclipse.cdt.codan.core.model.cfg.IBranchNode;
+import org.eclipse.cdt.codan.core.model.cfg.IConnectorNode;
+import org.eclipse.cdt.codan.core.model.cfg.IDecisionNode;
+import org.eclipse.cdt.codan.core.model.cfg.IExitNode;
+import org.eclipse.cdt.codan.core.model.cfg.IJumpNode;
+import org.eclipse.cdt.codan.core.model.cfg.IPlainNode;
+import org.eclipse.cdt.codan.core.model.cfg.ISingleOutgoing;
+import org.eclipse.cdt.codan.core.model.cfg.IStartNode;
+import org.eclipse.cdt.codan.core.tests.CodanFastCxxAstTestCase;
+import org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock;
+import org.eclipse.cdt.codan.internal.core.cfg.ControlFlowGraph;
+import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.dom.ast.c.CASTVisitor;
+import org.eclipse.cdt.core.parser.ParserLanguage;
+
+/**
+ * Tests for ControlFlowGraph
+ */
+public class ControlFlowGraphTest extends CodanFastCxxAstTestCase {
+ ControlFlowGraph graph;
+
+ /**
+ * @param ast
+ */
+ private void processAst(IASTTranslationUnit ast) {
+ CASTVisitor visitor = new CASTVisitor() {
+ {
+ shouldVisitDeclarations = true;
+ }
+
+ @Override
+ public int visit(IASTDeclaration decl) {
+ if (decl instanceof IASTFunctionDefinition) {
+ graph = new ControlFlowGraphBuilder().build((IASTFunctionDefinition) decl);
+ return PROCESS_ABORT;
+ }
+ return PROCESS_CONTINUE;
+ }
+ };
+ ast.accept(visitor);
+ }
+
+ private void checkCfg() {
+ checkCfg(true);
+ }
+
+ /**
+ *
+ */
+ private void checkCfg(boolean decision) {
+ assertNotNull(graph);
+ assertNotNull(graph.getStartNode());
+ Collection<IBasicBlock> nodes = graph.getNodes();
+ for (Iterator<IBasicBlock> iterator = nodes.iterator(); iterator.hasNext();) {
+ IBasicBlock node = iterator.next();
+ checkNode(node, decision);
+ }
+ }
+
+ /**
+ * @param node
+ */
+ private void checkNode(IBasicBlock node, boolean decision) {
+ IBasicBlock[] incomingNodes = node.getIncomingNodes();
+ nodes: for (int i = 0; i < incomingNodes.length; i++) {
+ IBasicBlock b = incomingNodes[i];
+ if (b == null) {
+ if (node instanceof IBranchNode)
+ continue nodes;
+ // check if dead node
+ Iterator<IBasicBlock> iterator = graph.getUnconnectedNodeIterator();
+ boolean dead = false;
+ for (; iterator.hasNext();) {
+ IBasicBlock d = iterator.next();
+ if (node == d) {
+ dead = true;
+ break;
+ }
+ }
+ if (!dead)
+ fail("Block " + node + " prev is null");
+ } else if (!contains(node, b.getOutgoingNodes()))
+ fail("Block " + node + " inconsitent prev/next " + b);
+ }
+ IBasicBlock[] outgoingNodes = node.getOutgoingNodes();
+ for (int i = 0; i < outgoingNodes.length; i++) {
+ IBasicBlock b = outgoingNodes[i];
+ if (b == null)
+ fail("Block " + node + " next is null");
+ if (!contains(node, b.getIncomingNodes()))
+ fail("Block " + node + " inconsitent next/prev " + b);
+ }
+ if (node instanceof IDecisionNode && decision) {
+ assertTrue("decision node outgoing size " + node.getOutgoingSize(), node.getOutgoingSize() >= 1);
+ assertNotNull(((IDecisionNode) node).getMergeNode());
+ }
+ }
+
+ /**
+ * @param node
+ * @param outgoingIterator
+ * @return
+ */
+ private boolean contains(IBasicBlock node, IBasicBlock[] blocks) {
+ for (int i = 0; i < blocks.length; i++) {
+ IBasicBlock b = blocks[i];
+ if (b.equals(node))
+ return true;
+ }
+ return false;
+ }
+
+ protected void buildAndCheck(String code) {
+ buildAndCheck(code, false);
+ }
+
+ protected void buildAndCheck_cpp(String code) {
+ buildAndCheck(code, true);
+ }
+
+ /**
+ * @param file
+ */
+ protected void buildAndCheck(String code, boolean cpp) {
+ buildCfg(code, cpp);
+ checkCfg();
+ }
+
+ /**
+ * @param code
+ * @param cpp
+ */
+ private void buildCfg(String code, boolean cpp) {
+ parse(code, cpp ? ParserLanguage.CPP : ParserLanguage.C, true);
+ processAst(tu);
+ }
+
+ private void buildCfg_C(String code) {
+ parse(code, ParserLanguage.C, true);
+ processAst(tu);
+ }
+
+ private void buildCfg_CPP(String code) {
+ parse(code, ParserLanguage.CPP, true);
+ processAst(tu);
+ }
+
+ /**
+ * @param des
+ * @return
+ */
+ private String data(IBasicBlock des) {
+ return ((AbstractBasicBlock) des).toStringData();
+ }
+
+ /**
+ * Return first node after the branch
+ *
+ * @param des
+ * @return
+ */
+ private IBasicBlock branchEnd(IDecisionNode des, String label) {
+ IBasicBlock[] outgoingNodes = des.getOutgoingNodes();
+ for (int i = 0; i < outgoingNodes.length; i++) {
+ IBasicBlock iBasicBlock = outgoingNodes[i];
+ IBranchNode bn = (IBranchNode) iBasicBlock;
+ if (label.equals(bn.getLabel()))
+ return bn.getOutgoing();
+ }
+ return null;
+ }
+
+ /**
+ * Return node where control jumps, following the chain until jump is hit
+ *
+ * @param a
+ * @return
+ */
+ private IBasicBlock jumpEnd(IBasicBlock a) {
+ if (a instanceof IJumpNode)
+ return ((IJumpNode) a).getOutgoing();
+ if (a instanceof ISingleOutgoing)
+ return jumpEnd(((ISingleOutgoing) a).getOutgoing());
+ return null;
+ }
+
+ @Override
+ public boolean isCpp() {
+ return true;
+ }
+
+ // main() {
+ // int a;
+ // a=1;
+ // }
+ public void test_basic() {
+ buildAndCheck(getAboveComment());
+ }
+
+ // main() {
+ // int a=10;
+ // while (a--) {
+ // a=a-2;
+ // }
+ // }
+ public void test_while() {
+ buildAndCheck(getAboveComment());
+ IStartNode startNode = graph.getStartNode();
+ IPlainNode decl = (IPlainNode) startNode.getOutgoing();
+ IConnectorNode conn = (IConnectorNode) decl.getOutgoing();
+ IDecisionNode des = (IDecisionNode) conn.getOutgoing();
+ assertEquals("a--", data(des));
+ IPlainNode bThen = (IPlainNode) branchEnd(des, IBranchNode.THEN);
+ assertEquals("a=a-2;", data(bThen));
+ IBasicBlock bElse = branchEnd(des, IBranchNode.ELSE);
+ IBasicBlock m2 = jumpEnd(bThen);
+ IBasicBlock m1 = jumpEnd(bElse);
+ assertSame(conn, m2);
+ IExitNode ret = (IExitNode) ((IConnectorNode) m1).getOutgoing();
+ }
+
+ // main() {
+ // int a=10;
+ // if (a--) {
+ // a=a-2;
+ // }
+ // }
+ public void test_if() {
+ buildAndCheck(getAboveComment());
+ IStartNode startNode = graph.getStartNode();
+ IPlainNode decl = (IPlainNode) startNode.getOutgoing();
+ IDecisionNode des = (IDecisionNode) decl.getOutgoing();
+ assertEquals("a--", data(des));
+ IPlainNode bThen = (IPlainNode) branchEnd(des, IBranchNode.THEN);
+ assertEquals("a=a-2;", data(bThen));
+ IBasicBlock bElse = branchEnd(des, IBranchNode.ELSE);
+ IBasicBlock m2 = jumpEnd(bThen);
+ IBasicBlock m1 = jumpEnd(bElse);
+ assertSame(m1, m2);
+ }
+
+ // main() {
+ // int a=10;
+ // if (a--) {
+ // return;
+ // }
+ // }
+ public void test_if_ret() {
+ buildAndCheck(getAboveComment());
+ IStartNode startNode = graph.getStartNode();
+ IPlainNode decl = (IPlainNode) startNode.getOutgoing();
+ IDecisionNode des = (IDecisionNode) decl.getOutgoing();
+ assertEquals("a--", data(des));
+ IExitNode bThen = (IExitNode) branchEnd(des, IBranchNode.THEN);
+ IBasicBlock bElse = branchEnd(des, IBranchNode.ELSE);
+ IBasicBlock m1 = jumpEnd(bElse);
+ }
+
+ // main() {
+ // return;
+ // a++;
+ // }
+ public void test_dead() {
+ buildCfg(getAboveComment(), false);
+ IStartNode startNode = graph.getStartNode();
+ IExitNode ret = (IExitNode) startNode.getOutgoing();
+ assertEquals(1, graph.getUnconnectedNodeSize());
+ }
+
+ // main() {
+ // int a=10;
+ // if (a--) {
+ // return;
+ // a++;
+ // }
+ // }
+ public void test_if_dead() {
+ buildCfg(getAboveComment(), false);
+ IStartNode startNode = graph.getStartNode();
+ IPlainNode decl = (IPlainNode) startNode.getOutgoing();
+ IDecisionNode des = (IDecisionNode) decl.getOutgoing();
+ assertEquals("a--", data(des));
+ IExitNode bThen = (IExitNode) branchEnd(des, IBranchNode.THEN);
+ IBasicBlock bElse = branchEnd(des, IBranchNode.ELSE);
+ IBasicBlock m1 = jumpEnd(bElse);
+ assertEquals(1, graph.getUnconnectedNodeSize());
+ }
+
+ // foo(int x) {
+ // int a=10;
+ // if (a--) {
+ // if (x<0)
+ // a++;
+ // }
+ // }
+ public void test_ifif() {
+ buildAndCheck(getAboveComment());
+ IStartNode startNode = graph.getStartNode();
+ IPlainNode decl = (IPlainNode) startNode.getOutgoing();
+ IDecisionNode des = (IDecisionNode) decl.getOutgoing();
+ assertEquals("a--", data(des));
+ IDecisionNode bThen = (IDecisionNode) branchEnd(des, IBranchNode.THEN);
+ assertEquals("x<0", data(bThen));
+ IBasicBlock bElse = branchEnd(des, IBranchNode.ELSE);
+ IBasicBlock m2 = jumpEnd(branchEnd(bThen, IBranchNode.THEN));
+ IBasicBlock m1 = jumpEnd(bElse);
+ IBasicBlock m3 = jumpEnd(m2);
+ assertSame(m1, m3);
+ }
+
+ // int foo() {
+ // throw 5;
+ // }
+ public void test_throw() {
+ buildAndCheck_cpp(getAboveComment());
+ IStartNode startNode = graph.getStartNode();
+ assertEquals(1, graph.getExitNodeSize());
+ Iterator<IExitNode> exitNodeIterator = graph.getExitNodeIterator();
+ IExitNode exit = exitNodeIterator.next();
+ assertEquals("throw 5;", data(exit));
+ }
+
+ // int foo() {
+ // exit(0);
+ // }
+ public void test_exit() {
+ buildAndCheck(getAboveComment());
+ IStartNode startNode = graph.getStartNode();
+ assertEquals(1, graph.getExitNodeSize());
+ Iterator<IExitNode> exitNodeIterator = graph.getExitNodeIterator();
+ IExitNode exit = exitNodeIterator.next();
+ assertEquals("exit(0);", data(exit));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.cdt.codan.core.test.CodanFastCxxAstTestCase#getChecker()
+ */
+ @Override
+ public IChecker getChecker() {
+ return null;
+ }
+
+ // int foo() {
+ // void * p;
+ // try {
+ // *p = 1;
+ // } catch (int e) {
+ // };
+ // }
+ public void test_try() {
+ buildAndCheck_cpp(getAboveComment());
+ IStartNode startNode = graph.getStartNode();
+ IPlainNode decl = (IPlainNode) startNode.getOutgoing();
+ IDecisionNode des = (IDecisionNode) decl.getOutgoing();
+ //assertEquals("", data(des));
+ IPlainNode bThen = (IPlainNode) branchEnd(des, IBranchNode.TRY_BODY);
+ assertEquals("*p = 1;", data(bThen));
+ IBasicBlock bElse = null;
+ IBasicBlock[] outgoingNodes = des.getOutgoingNodes();
+ for (int i = 1; i < outgoingNodes.length; i++) {
+ IBasicBlock iBasicBlock = outgoingNodes[i];
+ IBranchNode bn = (IBranchNode) iBasicBlock;
+ bElse = bn;
+ }
+ IBasicBlock m2 = jumpEnd(bThen);
+ IBasicBlock m1 = jumpEnd(bElse);
+ assertSame(m1, m2);
+ }
+
+ // foo() {
+ // switch (0) {
+ // case 1: ;
+ // }
+ // }
+ public void test_switch1() {
+ buildCfg(getAboveComment(), false);
+ checkCfg(false);
+ }
+
+ // foo() {
+ // switch (0) {
+ // case 1: break;
+ // }
+ // }
+ public void test_switchbreak() {
+ buildCfg(getAboveComment(), false);
+ checkCfg(false);
+ }
+
+ // foo() {
+ // switch (0) {
+ // a++;
+ // }
+ // }
+ public void test_switchdead() {
+ buildCfg(getAboveComment(), false);
+ checkCfg(false);
+ IStartNode startNode = graph.getStartNode();
+ assertEquals(1, graph.getUnconnectedNodeSize());
+ }
+
+ // foo() {
+ // int a=10,x=5;
+ // if (x<0)
+ // a++;
+ // }
+ public void test_deadbranch() {
+ buildCfg(getAboveComment(), false);
+ checkCfg(false);
+ IStartNode startNode = graph.getStartNode();
+ IPlainNode decl = (IPlainNode) startNode.getOutgoing();
+ IDecisionNode des = (IDecisionNode) decl.getOutgoing();
+ assertEquals("x<0", data(des));
+ IBasicBlock bElse = branchEnd(des, IBranchNode.ELSE);
+ IBasicBlock m2 = jumpEnd(branchEnd(des, IBranchNode.THEN));
+ IBasicBlock m1 = jumpEnd(bElse);
+ assertNull(m2);
+ assertNotNull(m1);
+ }
+
+ // int test1_f()
+ // {
+ // while (1)
+ // {
+ // }
+ // }
+ public void test_infiniloop() {
+ buildCfg_C(getAboveComment());
+ checkCfg(false);
+ IStartNode startNode = graph.getStartNode();
+ IConnectorNode conn = (IConnectorNode) startNode.getOutgoing();
+ IDecisionNode des = (IDecisionNode) conn.getOutgoing();
+ assertEquals("1", data(des));
+ IBasicBlock bElse = branchEnd(des, IBranchNode.ELSE);
+ IBasicBlock bThen = branchEnd(des, IBranchNode.THEN);
+ IBasicBlock m2 = jumpEnd(bThen);
+ IBasicBlock m1 = jumpEnd(bElse);
+ assertNotNull(m2);
+ assertNull(m1);
+ }
+
+ // void foo() {
+ // for (int i=0;i<N;i++) {
+ // bar();
+ // }
+ //}
+ public void test_for() {
+ buildCfg_CPP(getAboveComment());
+ checkCfg(false);
+ IStartNode startNode = graph.getStartNode();
+ IPlainNode decl = (IPlainNode) startNode.getOutgoing();
+ IConnectorNode conn = (IConnectorNode) decl.getOutgoing();
+ IDecisionNode des = (IDecisionNode) conn.getOutgoing();
+ assertEquals("i<N", data(des));
+ IPlainNode bThen = (IPlainNode) branchEnd(des, IBranchNode.THEN);
+ assertEquals("bar();", data(bThen));
+ IBasicBlock bElse = branchEnd(des, IBranchNode.ELSE);
+ IBasicBlock m1 = jumpEnd(bElse);
+ IBasicBlock m2 = bThen.getOutgoing();
+ assertNotNull(m1);
+ assertSame(conn, jumpEnd(bThen));
+ assertEquals("i++", data(((IConnectorNode) m2).getOutgoing()));
+ }
+
+ // void foo() {
+ // for (int i : arr) {
+ // bar();
+ // }
+ // }
+ public void test_range_loop() {
+ buildCfg_CPP(getAboveComment());
+ checkCfg(false);
+ IStartNode startNode = graph.getStartNode();
+ IPlainNode decl = (IPlainNode) startNode.getOutgoing();
+ IConnectorNode conn = (IConnectorNode) decl.getOutgoing();
+ IDecisionNode des = (IDecisionNode) conn.getOutgoing();
+ assertEquals("arr", data(des)); // condition
+ IPlainNode bThen = (IPlainNode) branchEnd(des, IBranchNode.THEN);
+ assertEquals("bar();", data(bThen));
+ IBasicBlock bElse = branchEnd(des, IBranchNode.ELSE);
+ assertNotNull(bElse);
+ IBasicBlock m2 = bThen.getOutgoing();
+ IBasicBlock m1 = jumpEnd(bElse);
+ assertNotNull(m1);
+ assertSame(conn, jumpEnd(bThen));
+ assertEquals("", data(((IConnectorNode) m2).getOutgoing())); // increment
+ }
+
+ // int main() {
+ // goto b;
+ // a:
+ // return 2;
+ // b:
+ // goto a;
+ // }
+ public void test_bad_labels() {
+ buildAndCheck(getAboveComment());
+ assertEquals(0, graph.getUnconnectedNodeSize());
+ IStartNode startNode = graph.getStartNode();
+ IJumpNode gotoB = (IJumpNode) startNode.getOutgoing();
+ IConnectorNode bConn = gotoB.getJumpNode();
+ IJumpNode gotoA = (IJumpNode) bConn.getOutgoing();
+ IConnectorNode aConn = gotoA.getJumpNode();
+ IExitNode ret = (IExitNode) aConn.getOutgoing();
+ assertEquals("return 2;", data(ret));
+ }
+
+ // int main(int a) {
+ // goto b;
+ // if (a) return 2;
+ // b:
+ // return 1;
+ // }
+ public void test_labels_if() {
+ buildAndCheck(getAboveComment());
+ assertEquals(1, graph.getUnconnectedNodeSize()); // if is dead code
+ }
+
+ // int main(int a) {
+ // goto b;
+ // b:;
+ // }
+ public void test_goto() {
+ buildAndCheck(getAboveComment());
+ assertEquals(0, graph.getUnconnectedNodeSize());
+ }
+
+ // int main() {
+ // return 1;
+ // a:
+ // return 2;
+ // b:
+ // goto a;
+ // }
+ public void test_dead_labels() {
+ buildAndCheck(getAboveComment());
+ assertEquals(1, graph.getUnconnectedNodeSize());
+ IStartNode startNode = graph.getStartNode();
+ IExitNode ret = (IExitNode) startNode.getOutgoing();
+ assertEquals("return 1;", data(ret));
+ IBranchNode labelB = (IBranchNode) graph.getUnconnectedNodeIterator().next(); // BranchNode: b:
+ Collection<IBasicBlock> res = graph.getDeadNodes();
+ assertEquals(6, res.size());
+
+ IJumpNode gotoA = (IJumpNode) ((IConnectorNode) labelB.getOutgoing()).getOutgoing();
+ IConnectorNode aConn = gotoA.getJumpNode();
+ IExitNode ret2 = (IExitNode) aConn.getOutgoing();
+ assertEquals("return 2;", data(ret2));
+ assertTrue(res.contains(gotoA));// goto a;
+ assertTrue(res.contains(aConn));
+ assertTrue(res.contains(ret2)); // return 2;
+ assertTrue(res.contains(ret2.getIncoming())); // Branch Node: a:
+ }
+
+ // int main(int a) {
+ // if (a) {
+ // return 1;
+ // } else {
+ // return 2;
+ // }
+ // a++;
+ // }
+ public void test_dead_connector() {
+ buildAndCheck(getAboveComment());
+ assertEquals(1, graph.getUnconnectedNodeSize());
+ IConnectorNode connIf = (IConnectorNode) graph.getUnconnectedNodeIterator().next();
+ assertEquals("a++;", data(connIf.getOutgoing()));
+ }
+
+ // int main(int a) {
+ // for (;1;a++) {
+ // return 1;
+ // }
+ // a--;
+ // }
+ public void test_dead_connector_for() {
+ buildAndCheck(getAboveComment());
+ assertEquals(2, graph.getUnconnectedNodeSize());
+ IConnectorNode conn = (IConnectorNode) graph.getUnconnectedNodeIterator().next();
+ assertEquals("a++", data(conn.getOutgoing()));
+ }
+
+ // int main(int a) {
+ // while (0) {
+ // return 1;
+ // }
+ //
+ // a++;
+ // }
+ public void test_dead_connector_while() {
+ buildAndCheck(getAboveComment());
+ assertEquals(1, graph.getUnconnectedNodeSize());
+ IBranchNode trueBranch = (IBranchNode) graph.getUnconnectedNodeIterator().next();
+ assertEquals("return 1;", data(trueBranch.getOutgoing()));
+ }
+
+ // int foo(int x) {
+ // switch (x) {
+ // case 0:
+ // return 42;;
+ // default:
+ // }
+ // }
+ public void test_dead_statement_in_switch() throws Exception {
+ buildAndCheck(getAboveComment());
+ IDecisionNode swittch = (IDecisionNode) graph.getStartNode().getOutgoing();
+ Collection<IBasicBlock> deadNodes = graph.getDeadNodes();
+ // Make sure the switch statement's merge node has not been marked as dead.
+ assertFalse(deadNodes.contains(swittch.getMergeNode()));
+ }
+
+ // int main(int a) {
+ // switch (a) {
+ // case 1: {
+ // break;
+ // }
+ // case 2: {
+ // break;
+ // }
+ // }
+ // }
+ public void test_switch_break_in_compound_statement() {
+ // Test that the target node of the jump for the 'break' in a case
+ // is the connector node at the end of the switch, not the connector
+ // node for the next case.
+ buildAndCheck(getAboveComment());
+ IDecisionNode swittch = (IDecisionNode) graph.getStartNode().getOutgoing();
+ IPlainNode case1Branch = (IPlainNode) swittch.getOutgoingNodes()[0];
+ IJumpNode case1Jump = (IJumpNode) case1Branch.getOutgoing();
+ assertEquals(swittch.getMergeNode(), case1Jump.getJumpNode());
+ }
+
+ // int main(int a) {
+ // switch (a) {
+ // }
+ // }
+ public void test_empty_switch() {
+ buildAndCheck(getAboveComment());
+ // Decision node should be optimized away entirely
+ assertFalse(graph.getStartNode() instanceof IDecisionNode);
+ }
+
+ // int main(int a) {
+ // switch (a) {
+ // case 1: {
+ // break;
+ // }
+ // }
+ // }
+ public void test_switch_no_explicit_default() {
+ buildAndCheck(getAboveComment());
+ IDecisionNode swittch = (IDecisionNode) graph.getStartNode().getOutgoing();
+ assertTrue(swittch.getOutgoingSize() == 2);
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/cxx/CxxAstUtilsTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/cxx/CxxAstUtilsTest.java
new file mode 100644
index 00000000000..2133f771f5e
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/cxx/CxxAstUtilsTest.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2012 QNX Software Systems
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems (Alena Laskavaia) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.cxx;
+
+import java.io.IOException;
+
+import org.eclipse.cdt.codan.core.model.IChecker;
+import org.eclipse.cdt.codan.core.tests.CodanFastCxxAstTestCase;
+import org.eclipse.cdt.core.dom.ast.ASTVisitor;
+import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTStatement;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
+import org.eclipse.cdt.core.dom.ast.IType;
+import org.eclipse.cdt.core.dom.ast.c.ICBasicType;
+
+/**
+ * Test CxxAstUtils
+ */
+public class CxxAstUtilsTest extends CodanFastCxxAstTestCase {
+ @Override
+ public IChecker getChecker() {
+ return null; // not testing checker
+ }
+
+ // typedef int A;
+ // typedef A B;
+ // void main() {
+ // B x;
+ // }
+ public void testUnwindTypedef() throws IOException {
+ String code = getAboveComment();
+ IASTTranslationUnit tu = parse(code);
+ final Object result[] = new Object[1];
+ ASTVisitor astVisitor = new ASTVisitor() {
+ {
+ shouldVisitDeclarations = true;
+ }
+
+ @Override
+ public int visit(IASTDeclaration decl) {
+ if (decl instanceof IASTSimpleDeclaration) {
+ IASTSimpleDeclaration sdecl = (IASTSimpleDeclaration) decl;
+ IASTDeclSpecifier spec = sdecl.getDeclSpecifier();
+ if (spec instanceof IASTNamedTypeSpecifier) {
+ IASTName tname = ((IASTNamedTypeSpecifier) spec).getName();
+ IType typeName = (IType) tname.resolveBinding();
+ result[0] = CxxAstUtils.unwindTypedef(typeName);
+ }
+ }
+ return PROCESS_CONTINUE;
+ }
+ };
+ tu.accept(astVisitor);
+ assertNotNull(result[0]);
+ ICBasicType type = (ICBasicType) result[0];
+ assertEquals(Kind.eInt, type.getKind());
+ }
+
+ // #define AAA a
+ // void main (){
+ // AAA;
+ // b;
+ //}
+ public void testIsInMacro() throws IOException {
+ String code = getAboveComment();
+ IASTTranslationUnit tu = parse(code);
+ final Object result[] = new Object[2];
+ ASTVisitor astVisitor = new ASTVisitor() {
+ int i;
+ {
+ shouldVisitStatements = true;
+ }
+
+ @Override
+ public int visit(IASTStatement stmt) {
+ if (stmt instanceof IASTExpressionStatement) {
+ boolean check = CxxAstUtils.isInMacro(((IASTExpressionStatement) stmt).getExpression());
+ result[i] = check;
+ i++;
+ }
+ return PROCESS_CONTINUE;
+ }
+ };
+ tu.accept(astVisitor);
+ assertNotNull("Stmt not found", result[0]); //$NON-NLS-1$
+ assertTrue((Boolean) result[0]);
+ assertFalse((Boolean) result[1]);
+ }
+
+ //void f() __attribute__((noreturn));
+ //
+ //int test() {
+ // a();
+ // f();
+ // exit(0);
+ //}
+ public void testExitStatement() throws IOException {
+ String code = getAboveComment();
+ IASTTranslationUnit tu = parse(code);
+ final Object result[] = new Object[4];
+ ASTVisitor astVisitor = new ASTVisitor() {
+ int i;
+ {
+ shouldVisitStatements = true;
+ }
+
+ @Override
+ public int visit(IASTStatement stmt) {
+ boolean check = CxxAstUtils.isExitStatement(stmt);
+ result[i] = check;
+ i++;
+ return PROCESS_CONTINUE;
+ }
+ };
+ tu.accept(astVisitor);
+ assertNotNull("Stmt not found", result[0]); //$NON-NLS-1$
+ assertFalse((Boolean) result[0]); // compound body
+ assertFalse((Boolean) result[1]);
+ assertTrue((Boolean) result[2]);
+ assertTrue((Boolean) result[3]);
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/cxx/externaltool/ArgsSeparatorTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/cxx/externaltool/ArgsSeparatorTest.java
new file mode 100644
index 00000000000..0623c6477a3
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/cxx/externaltool/ArgsSeparatorTest.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Google, Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alex Ruiz (Google) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.cxx.externaltool;
+
+import static org.junit.Assert.assertArrayEquals;
+import junit.framework.TestCase;
+
+/**
+ * Tests for <code>{@link ArgsSeparator}</code>.
+ */
+@SuppressWarnings("nls")
+public class ArgsSeparatorTest extends TestCase {
+ private ArgsSeparator separator;
+
+ @Override
+ protected void setUp() {
+ separator = new ArgsSeparator();
+ }
+
+ public void testWithSpaceAsDelimiter() {
+ String[] args = separator.splitArguments("abc def ghi");
+ assertArrayEquals(new String[] { "abc", "def", "ghi" }, args);
+ }
+
+ public void testWithSingleQuote() {
+ String[] args = separator.splitArguments("abc 'def ghi' jkl");
+ assertArrayEquals(new String[] { "abc", "def ghi", "jkl" }, args);
+ }
+
+ public void testWithDoubleQuote() {
+ String[] args = separator.splitArguments("abc \"def ghi\" jkl");
+ assertArrayEquals(new String[] { "abc", "def ghi", "jkl" }, args);
+ }
+
+ public void testWithEscapedSingleQuote() {
+ String[] args = separator.splitArguments("abc 'def \\' ghi' jkl");
+ assertArrayEquals(new String[] { "abc", "def \\' ghi", "jkl" }, args);
+ }
+
+ public void testWithEscapedDoubleQuote() {
+ String[] args = separator.splitArguments("abc 'def \\\" ghi' jkl");
+ assertArrayEquals(new String[] { "abc", "def \\\" ghi", "jkl" }, args);
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/AbstractClassInstantiationCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/AbstractClassInstantiationCheckerTest.java
new file mode 100644
index 00000000000..2bb86d7377f
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/AbstractClassInstantiationCheckerTest.java
@@ -0,0 +1,376 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 Anton Gorenkov
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anton Gorenkov - initial implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.cdt.codan.internal.checkers.AbstractClassInstantiationChecker;
+
+/**
+ * Test for {@see AbstractClassInstantiationChecker} class
+ */
+public class AbstractClassInstantiationCheckerTest extends CheckerTestCase {
+ @Override
+ public boolean isCpp() {
+ return true;
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems(AbstractClassInstantiationChecker.ER_ID);
+ }
+
+ // class C {
+ // virtual void f() {}
+ // };
+ // void scope () {
+ // C c; // No errors.
+ // }
+ public void testNotAbstractClassCreationOnStack() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class C {
+ // virtual void f() {}
+ // };
+ // void scope () {
+ // C* c = new C(); // No errors.
+ // }
+ public void testNotAbstractClassCreationWithNew() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class C {
+ // virtual void f() {}
+ // };
+ // void scope () {
+ // C::C(); // No errors.
+ // }
+ public void testNotAbstractClassCreationWithDirectConstructorCall() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class C {
+ // virtual void f() = 0;
+ // };
+ // void scope () {
+ // C* c1; // No errors.
+ // C& c2; // No errors.
+ // }
+ public void testAbstractClassPointerOrReverenceDeclaration() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class C {
+ // virtual void f() = 0;
+ // };
+ // typedef C typedefC;
+ // void scope () {
+ // C c; // 1 error for: C::f().
+ // typedefC tc; // 1 error for: C::f().
+ // }
+ public void testAbstractClassCreationOnStack() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(6, 7);
+ }
+
+ // class C {
+ // virtual void f() = 0;
+ // };
+ // typedef C typedefC;
+ // void scope () {
+ // C *c1, c2, &c3; // 1 error for: C::f().
+ // typedefC *tc1, tc2, &tc3; // 1 error for: C::f().
+ // }
+ public void testAbstractClassCreationOnStackWithRefAndPtr() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(6, 7);
+ }
+
+ // class C {
+ // virtual void f() = 0;
+ // };
+ // typedef C typedefC;
+ // void test ( C _c ) {} // 1 error for: C::f().
+ // void test2 ( typedefC _c ) {} // 1 error for: C::f().
+ // void test3 ( C _c, typedefC _c ) {} // 2 errors for: C::f(), C::f().
+ // void test4 ( C ) {} // 1 error for: C::f().
+ // void test5 ( C* _c ) {} // No errors.
+ // void test6 ( typedefC& _c ) {} // No errors.
+ public void testAbstractClassCreationAsFunctionParameter() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(5, 6, 7, 7, 8);
+ }
+
+ // class C {
+ // virtual void f() = 0;
+ // };
+ // template <typename C> // No errors.
+ // void test () {}
+ public void testAbstractClassCreationAsFunctionTemplateParameter() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class C {
+ // virtual void f() = 0;
+ // };
+ // typedef C typedefC;
+ // void scope () {
+ // C* c1 = new C(); // 1 error for: C::f().
+ // C* c2 = new C[10]; // 1 error for: C::f().
+ // C* c3 = new typedefC(); // 1 error for: C::f().
+ // C* c4 = new typedefC; // 1 error for: C::f().
+ // C* c5 (new C()); // 1 error for: C::f().
+ // C* c6 (new typedefC()); // 1 error for: C::f().
+ // C* c7 = new typedefC[10]; // 1 error for: C::f().
+ // C** x1 = new C*(); // No errors.
+ // typedefC** x2 = new typedefC*(); // No errors.
+ // }
+ public void testAbstractClassCreationWithNew() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(6, 7, 8, 9, 10, 11, 12);
+ }
+
+ // class C {
+ // virtual void f() = 0;
+ // };
+ // typedef C typedefC;
+ // void scope () {
+ // C::C(); // 1 error for: C::f().
+ // typedefC::C(); // 1 error for: C::f().
+ // }
+ public void testAbstractClassCreationWithDirectConstructorCall() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(6, 7);
+ }
+
+ // namespace N {
+ // class C {
+ // virtual void f() = 0;
+ // };
+ // }
+ // void scope () {
+ // N::C* c = new N::C(); // 1 error for: N::C::f().
+ // }
+ public void testAbstractClassFromNamespace() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(7);
+ }
+
+ // class C {
+ // virtual void f() = 0;
+ // virtual int g() const = 0;
+ // };
+ // void scope () {
+ // C* c = new C(); // 2 errors for: C::f(), C::g().
+ // }
+ public void testAbstractClassWithAFewVirtualMethods() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(6, 6);
+ }
+
+ // class Base {
+ // virtual void f() = 0;
+ // };
+ // class Derived : public Base {
+ // };
+ // void scope () {
+ // Derived* d = new Derived(); // 1 error for: Base::f().
+ // }
+ public void testAbstractClassBecauseOfBaseClass() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(7);
+ }
+
+ // class Base {
+ // virtual void f() = 0;
+ // virtual int g() const = 0;
+ // };
+ // class Derived : public Base {
+ // virtual int g() const = 0;
+ // };
+ // void scope () {
+ // Derived* c = new Derived(); // 2 errors for: Base::f(), Derived::g().
+ // }
+ public void testAbstractClassWithVirtualRedefinition() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(9, 9);
+ }
+
+ // class C {
+ // virtual void f() = 0;
+ // };
+ // typedef C typedefC; // No errors.
+ public void testAbstractClassTypedef() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class C {
+ // virtual void f() = 0;
+ // };
+ // extern C typedefC; // 1 error for: C::f().
+ public void testExternAbstractClassDeclaration() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(4);
+ }
+
+ // class A {
+ // public:
+ // virtual ~A() = 0;
+ // };
+ //
+ // class B : public A {
+ // public:
+ // virtual ~B() {}
+ // };
+ //
+ // B b;
+ public void testPureVirtualDestructorOverride_1() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class A {
+ // public:
+ // virtual ~A() = 0;
+ // };
+ //
+ // class B : public A {
+ // };
+ //
+ // B b;
+ public void testPureVirtualDestructorOverride_2() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // struct MyInterface {
+ // virtual void doIt() = 0;
+ // };
+ //
+ // struct Empty: virtual public MyInterface {};
+ //
+ // struct Implementer: virtual public MyInterface {
+ // virtual void doIt();
+ // };
+ //
+ // struct Multiple: public Empty, public Implementer {};
+ //
+ // static Multiple sharedMultiple;
+ public void testDiamondInheritanceWithOneImplementor_bug351612a() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // struct MyInterface {
+ // virtual void doIt() = 0;
+ // };
+ //
+ // struct Empty: virtual public MyInterface {};
+ //
+ // struct Implementer: public MyInterface {
+ // virtual void doIt();
+ // };
+ //
+ // struct Multiple: public Empty, public Implementer {};
+ //
+ // static Multiple sharedMultiple;
+ public void testDiamondInheritanceWithOneImplementor_bug351612b() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(13);
+ }
+
+ // struct MyInterface {
+ // virtual void doIt() = 0;
+ // };
+ //
+ // struct Empty: public MyInterface {};
+ //
+ // struct Implementer: virtual public MyInterface {
+ // virtual void doIt();
+ // };
+ //
+ // struct Multiple: public Empty, public Implementer {};
+ //
+ // static Multiple sharedMultiple;
+ public void testDiamondInheritanceWithOneImplementor_bug351612c() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(13);
+ }
+
+ // struct MyInterface {
+ // virtual void doIt() = 0;
+ // };
+ //
+ // struct Empty: virtual public MyInterface {};
+ //
+ // struct Implementer: virtual public MyInterface {
+ // virtual void doIt();
+ // };
+ //
+ // struct Multiple: virtual public Implementer, virtual public Empty {};
+ //
+ // static Multiple sharedMultiple;
+ public void testDiamondInheritanceWithOneImplementor_bug419938() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // struct A {
+ // virtual void test(int) = 0;
+ // virtual ~A();
+ // };
+ //
+ // struct B : public A {
+ // using A::test;
+ // void test(const char*);
+ // void test(int);
+ // };
+ //
+ // int main() {
+ // B c;
+ // }
+ public void testUsingDeclarationInDerivedClass_bug414279() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // struct N {
+ // int node;
+ // };
+ //
+ // template <typename T>
+ // struct List {
+ // template <int T::*>
+ // struct Base {};
+ // };
+ //
+ // List<N>::Base<&N::node> base;
+ public void testUnsafeMethodCallException_bug416284() throws Exception {
+ // Just check that codan runs without any exceptions being thrown.
+ loadCodeAndRun(getAboveComment());
+ }
+
+ // template <int I>
+ // struct S : S<I - 1> {};
+ //
+ // S<1> waldo;
+ public void testMaxInstantiationDepth_430282() throws Exception {
+ // Just check that codan runs without any exceptions being thrown.
+ loadCodeAndRun(getAboveComment());
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentInConditionCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentInConditionCheckerTest.java
new file mode 100644
index 00000000000..aa1d42f4404
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentInConditionCheckerTest.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2016 Alena Laskavaia
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alena Laskavaia - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.cdt.codan.internal.core.model.CodanProblemMarker;
+import org.eclipse.core.resources.IMarker;
+
+/**
+ * Test for {@see AssignmentInConditionChecker} class
+ */
+public class AssignmentInConditionCheckerTest extends CheckerTestCase {
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems("org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem");
+ }
+
+ // main() {
+ // int a=1,b=3;
+ // if (a=b) b=4; // error here on line 3
+ // }
+ public void test_basic() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ }
+
+ // main() {
+ // int a=1,b=3;
+ //
+ // if ((a=b)) b--; // no error
+ // }
+ public void test_fixed() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // main() {
+ // int a=1,b=3;
+ // if ((a=b)!=0) b=4; // no error here on line 3
+ // }
+ public void test3() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // main() {
+ // int i,a[10];
+ // if (a[i]=0) b=4; // no error here on line 3
+ // }
+ public void test_array() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ }
+
+ // main() {
+ // int i,b=3;
+ // for (i = 0; i=b; i++) { // here
+ // }
+ // }
+ public void test_for() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ }
+
+ // main() {
+ // int i,b=3;
+ // while (i=b) { // here
+ // }
+ // }
+ public void test_while() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ }
+
+ // main() {
+ // int i,b=3;
+ // (i=b)?i++:b++; // here
+ // }
+ public void test_tri() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ }
+
+ // main() {
+ // int a=1,b=3;
+ // if (a=b) b=4; // error here on line 3
+ // }
+ public void test_basic_params() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ IMarker marker = checkErrorLine(3);
+ String arg = CodanProblemMarker.getProblemArgument(marker, 0);
+ assertEquals("a=b", arg); //$NON-NLS-1$
+ }
+
+ // main() {
+ // int i;
+ // while (i=b()) { // @suppress("Assignment in condition")
+ // }
+ // }
+ public void test_while2supp() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // main() {
+ // int i;
+ // while (i=b()) { /* @suppress("Assignment in condition") */
+ // }
+ // }
+ public void test_while3supp() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // #define LOOP() while (i=b() /* @suppress("Assignment in condition") */ ) { }
+ // main() {
+ // int i;
+ // LOOP();
+ // }
+ public void test_whileMacroSupp() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(4); // TODO: suppression does not work in macro body now
+ }
+
+ // #define LOOP() while (i=b()) { }
+ // main() {
+ // int i;
+ // LOOP(); // err
+ // }
+ public void test_whileMacro() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(4);
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentToItselfCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentToItselfCheckerTest.java
new file mode 100644
index 00000000000..869969c319c
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentToItselfCheckerTest.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Severin Gehwolf
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Severin Gehwolf - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.core.resources.IMarker;
+
+/**
+ * Test for {@see AssignmentToItselfChecker} class
+ */
+public class AssignmentToItselfCheckerTest extends CheckerTestCase {
+ // void main() {
+ // int x = 0;
+ // x = 10;
+ // }
+ public void testNoErrorConstants() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // void main() {
+ // int x = 10;
+ // int s = 10;
+ // x = s;
+ // }
+ public void testNoErrorVariables() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // void main() {
+ // int x = 0;
+ // x = x;
+ // }
+ public void testSimpleVariableSelfAssignmentError() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ }
+
+ // void main() {
+ // char str[] = "hello testing world";
+ // int x = 10;
+ // str[i] = str[i];
+ // }
+ public void testArraySelfAssignmentError() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(4);
+ }
+
+ // #define X a = 1
+ // void main() {
+ // int a;
+ // X;
+ // }
+ public void testNoError_Bug321933() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // void foo() {
+ // int x = 0; x
+ // = x;
+ // }
+ public void testMarkerOffset_Bug486610() throws Exception {
+ String code = getAboveComment();
+ loadCodeAndRun(code);
+ IMarker marker = checkErrorLine(2);
+ int start = marker.getAttribute(IMarker.CHAR_START, -1);
+ int end = marker.getAttribute(IMarker.CHAR_END, -1);
+ // The offset should start at the beginning of the expression "x = x"
+ assertEquals("x\n = x", code.substring(start, end));
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CaseBreakCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CaseBreakCheckerTest.java
new file mode 100644
index 00000000000..3f5f808b8fa
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CaseBreakCheckerTest.java
@@ -0,0 +1,580 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2015 Gil Barash
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Gil Barash - Initial implementation
+ * Sergey Prigogin (Google)
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import org.eclipse.cdt.codan.core.param.IProblemPreference;
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.cdt.codan.internal.checkers.CaseBreakChecker;
+
+/**
+ * Test for {@link CaseBreakChecker} class
+ */
+public class CaseBreakCheckerTest extends CheckerTestCase {
+ public static final String ER_ID = CaseBreakChecker.ER_ID;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ // Set default preferences.
+ setEmpty(false);
+ setLast(true);
+ }
+
+ // void foo(void) {
+ // int a;
+ // switch (a) {
+ // case 1:
+ // }
+ // }
+ public void testEmptyLastCaseBad() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(4);
+ }
+
+ // void foo(void) {
+ // int a;
+ // switch (a) {
+ // default:
+ // }
+ // }
+ public void testEmptyLastCaseDefaultBad() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(4);
+ }
+
+ // void foo(void) {
+ // int a, b;
+ // switch (a) {
+ // case 1:
+ // b = 2;
+ // }
+ // }
+ public void testLastCaseBad() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(5);
+ }
+
+ // void foo(void) {
+ // int a, b;
+ // switch (a) {
+ // case 1:
+ // case 2:
+ // b = 2;
+ // break;
+ // }
+ // }
+ public void testEmptyCaseBad() throws Exception {
+ setEmpty(true);
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(4);
+ }
+
+ // void foo(void) {
+ // int a;
+ // switch (a) {
+ // case 1:
+ // break;
+ // }
+ // }
+ public void testEmptyLastCaseOKbreak() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrorsOfKind(ER_ID);
+ }
+
+ // void foo(void) {
+ // int a;
+ // switch (a) {
+ // case 1:
+ // return;
+ // }
+ // }
+ public void testEmptyLastCaseWithReturn() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrorsOfKind(ER_ID);
+ }
+
+ // void foo(int a) {
+ // while (a--)
+ // switch (a) {
+ // case 1:
+ // continue;
+ // }
+ // }
+ public void testEmptyLastCaseWithContinue() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrorsOfKind(ER_ID);
+ }
+
+ // void foo(int a) {
+ //
+ // switch (a) {
+ // case 1:
+ // throw 1;
+ // }
+ // }
+ public void testEmptyLastCaseWithThrow() throws Exception {
+ loadCodeAndRunCpp(getAboveComment());
+ checkNoErrorsOfKind(ER_ID);
+ }
+
+ // void foo(void) {
+ // int a, b;
+ // switch (a) {
+ // case 1:
+ // b = 2;
+ // break;
+ // }
+ // }
+ public void testLastCaseOKbreak() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrorsOfKind(ER_ID);
+ }
+
+ // void foo(void) {
+ // int a, b;
+ // switch (a) {
+ // case 1:
+ // break;
+ // case 2:
+ // b = 2;
+ // break;
+ // }
+ // }
+ public void testEmptyCaseOKbreak() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrorsOfKind(ER_ID);
+ }
+
+ // void foo(void) {
+ // int a;
+ // switch (a) {
+ // case 1:
+ // /* no break */
+ // }
+ // }
+ public void testEmptyLastCaseOKcomment() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrorsOfKind(ER_ID);
+ }
+
+ // void foo(int a, int b) {
+ // switch (a) {
+ // case 1:
+ // switch (b) {
+ // case 2:
+ // break;
+ // }
+ // case 2:
+ // break;
+ // }
+ // }
+ public void testEmptyLastCaseTwoSwitches() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(7);
+ }
+
+ // void foo(void) {
+ // int a, b;
+ // switch (a) {
+ // case 1:
+ // b = 2;
+ // /* no break */
+ // }
+ // }
+ public void testLastCaseOKcomment() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrorsOfKind(ER_ID);
+ }
+
+ // void foo(void) {
+ // int a, b;
+ // switch (a) {
+ // case 1:
+ // /* no break */
+ // case 2:
+ // b = 2;
+ // break;
+ // }
+ public void testEmptyCaseOKcomment() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrorsOfKind(ER_ID);
+ }
+
+ // void foo(void) {
+ // int a, b;
+ // switch (a) {
+ // case 1:
+ // b = 2;
+ // /* no break */
+ // bye();
+ // }
+ // }
+ public void testLastCaseBadCommentNotLast() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(7);
+ }
+
+ // void foo(void) {
+ // int a, b;
+ // switch (a) {
+ // case 1:
+ // b = 2;
+ // /* no break */
+ // case 2:
+ // b = 2;
+ // /*no break*/
+ // case 3:
+ // b = 2;
+ // //no break
+ // case 4:
+ // b = 2;
+ // // no break
+ // case 5:
+ // b = 2;
+ // /* no brea */
+ // case 6:
+ // b = 2;
+ // /* no break1 */
+ // case 7:
+ // b = 2;
+ // /* fallthrough */
+ // }
+ // }
+ public void testDifferentComments() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(17,23);
+ }
+
+ // void foo(void) {
+ // int a, b;
+ // switch (a) {
+ // case 1: //err
+ // // lolo
+ // case 2: //err
+ // case 3://err
+ // }
+ //
+ // switch (a) {
+ // case 1:
+ // b = 2; // err
+ // // lolo
+ // case 2:
+ // b = 2; // err
+ // case 3: // err
+ // case 4:
+ // break;
+ // case 5: // err
+ // case 6: // err
+ // }
+ //
+ // switch (a) {
+ // case 1:
+ // b = 2; // err
+ // // lolo
+ // case 2:
+ // b = 2; //err
+ // case 3:
+ // b = 2;
+ // /* no break */
+ // case 4:
+ // b = 2; // err
+ // case 5:
+ // b = 2;
+ // break;
+ // case 6:
+ // b = 2;
+ // /* no break */
+ // b = 2; //err
+ // case 7:
+ // b = 2;//err
+ // }
+ //
+ // switch (a) {
+ // case 1:
+ // b = 2; // err
+ // // lolo
+ // case 2:
+ // b = 2; // err
+ // default: //err
+ // }
+ // }
+ public void testGeneral1() throws Exception {
+ setEmpty(true);
+ setLast(true);
+ loadCodeAndRun(getAboveComment());
+ checkErrorComments();
+ }
+
+ // void foo(void) {
+ // int a, b;
+ // switch (a) {
+ // case 1:
+ // b = 2;
+ // // lolo
+ // /* no break */
+ // case 2:
+ // b = 2;
+ // /* no break */
+ // // lolo
+ // case 3:
+ // /* no break */
+ // b = 2;
+ // // loo
+ // case 4:
+ // b = 2;
+ // // lolo
+ // /* no break */
+ // case 5:
+ // // lolo
+ // b = 2;
+ // /* no break */
+ // }
+ // }
+ public void testGeneralComments1() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(9, 14);
+ }
+
+ // void foo(void) {
+ // int a, b;
+ // switch (a) {
+ // case 0:
+ // switch( b ) {
+ // case 2: // err
+ // } // err
+ //
+ // case 1:
+ // switch( b ) {
+ // case 2:
+ // break;
+ // } // err
+ // case 3:
+ // switch( b ) {
+ // case 2:
+ // break;
+ // }
+ // break;
+ // case 4:
+ // switch( b ) {
+ // case 2:
+ // /* no break */
+ // } // err
+ // case 5:
+ // switch( b ) {
+ // case 2: // err
+ // }
+ // /* no break */
+ // }
+ // }
+ public void testNestedSwitches() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorComments();
+ }
+
+ // void foo(void) {
+ // int a, b;
+ // switch (a) {
+ // case 1:
+ // b = 2;
+ // }
+ // }
+ public void testLastCaseIgnore() throws Exception {
+ setLast(false);
+ loadCodeAndRun(getAboveComment());
+ checkNoErrorsOfKind(ER_ID);
+ setLast(true);
+ }
+
+ // void foo(void) {
+ // int a, b;
+ // switch (a) {
+ // case 1:
+ // case 2:
+ // b = 2;
+ // break;
+ // case 3: case 4:
+ // b = 2;
+ // break;
+ // }
+ // }
+ public void testEmptyCaseIgnore() throws Exception {
+ setEmpty(false);
+ loadCodeAndRun(getAboveComment());
+ checkNoErrorsOfKind(ER_ID);
+ }
+
+ // void foo(void) {
+ // int a;
+ // switch (a) {
+ // case 1:
+ // }
+ // }
+ public void testEmptyLastCaseIgnore() throws Exception {
+ String code = getAboveComment();
+ setLast(false);
+ loadCodeAndRun(code);
+ checkNoErrorsOfKind(ER_ID);
+ setLast(true);
+ setEmpty(false);
+ loadCodeAndRun(code);
+ checkErrorLine(4, ER_ID);
+ }
+
+ private void setLast(boolean val) {
+ IProblemPreference pref = getPreference(CaseBreakChecker.ER_ID, CaseBreakChecker.PARAM_LAST_CASE);
+ pref.setValue(val);
+ }
+
+ private void setEmpty(boolean val) {
+ IProblemPreference pref = getPreference(CaseBreakChecker.ER_ID, CaseBreakChecker.PARAM_EMPTY_CASE);
+ pref.setValue(val);
+ }
+
+ // void foo(int a) {
+ // switch (a) {
+ // case 1:
+ // while (a--)
+ // break; // err
+ // case 2:
+ // while (a--) {
+ // break;
+ // } // err
+ // }
+ // }
+ public void testEmptyCaseWithLoopBreak() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorComments();
+ }
+
+ // void foo(int a) {
+ // switch (a) {
+ // case 1: {
+ // break;
+ // }
+ // case 2: {
+ // a--;
+ // break;
+ // }
+ // }
+ // }
+ public void testCaseWithCurlyBrackets() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrorsOfKind(ER_ID);
+ }
+
+ // void foo(void) {
+ // int a;
+ // switch (a) {
+ // case 2:
+ // break;
+ // case 1:
+ // }
+ // }
+ public void testEmptyLastCaseError() throws Exception {
+ String code = getAboveComment();
+ setLast(true);
+ setEmpty(false);
+ loadCodeAndRun(code);
+ checkErrorLine(6, ER_ID);
+ setLast(false);
+ loadCodeAndRun(code);
+ checkNoErrorsOfKind(ER_ID);
+ }
+
+ // void foo(int a) {
+ // switch (a) {
+ // case 2:
+ // if (a*2<10)
+ // return;
+ // else
+ // break;
+ // case 1:
+ // break;
+ // }
+ // }
+ public void testIf() throws Exception {
+ String code = getAboveComment();
+ loadCodeAndRun(code);
+ checkNoErrorsOfKind(ER_ID);
+ }
+
+ // void foo(int a) {
+ // switch(a) {
+ // case 2:
+ // if (a*2<10)
+ // return;
+ // else
+ // a++;
+ // case 1:
+ // break;
+ // }
+ // }
+ public void testIfErr() throws Exception {
+ String code = getAboveComment();
+ loadCodeAndRun(code);
+ checkErrorLine(7, ER_ID);
+ }
+
+ // #define DEFINE_BREAK {break;}
+ // void foo(int a) {
+ // switch (a) {
+ // case 1:
+ // DEFINE_BREAK // No warning here
+ // }
+ // }
+ public void testBreakInBraces() throws Exception {
+ String code = getAboveComment();
+ loadCodeAndRun(code);
+ checkNoErrorsOfKind(ER_ID);
+ }
+
+ // #define MY_MACRO(i) \
+ // case i: { \
+ // }
+ //
+ // void f() {
+ // int x;
+ // switch (x) {
+ // MY_MACRO(1) // No warning here
+ // }
+ // }
+ public void testInMacro() throws Exception {
+ String code = getAboveComment();
+ loadCodeAndRun(code);
+ checkNoErrorsOfKind(ER_ID);
+ }
+
+ // void foo() {
+ // switch (0)
+ // default: {
+ // }
+ // }
+ public void testEmptyCompoundStatement() throws Exception {
+ String code = getAboveComment();
+ loadCodeAndRun(code);
+ checkErrorLine(4, ER_ID);
+ }
+
+ // void foo() {
+ // switch (0) {
+ // case 0:
+ // return 42;;
+ // case 1:
+ // break;
+ // }
+ // }
+ public void testDoubleSemicolon_bug441714() throws Exception {
+ String code = getAboveComment();
+ loadCodeAndRun(code);
+ checkNoErrorsOfKind(ER_ID);
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CatchByReferenceTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CatchByReferenceTest.java
new file mode 100644
index 00000000000..30fe974c204
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CatchByReferenceTest.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2011 Alena Laskavaia
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alena Laskavaia - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.cdt.codan.internal.checkers.CatchByReference;
+
+/**
+ * Test for {@see CatchByReference} class
+ */
+public class CatchByReferenceTest extends CheckerTestCase {
+ @Override
+ public boolean isCpp() {
+ return true;
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems(CatchByReference.ER_ID);
+ }
+
+ // void main() {
+ // try {
+ // foo();
+ // } catch (int e) {
+ // }
+ // }
+ public void test_int() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class C {};
+ // void main() {
+ // try {
+ // foo();
+ // } catch (C e) {
+ // }
+ // }
+ public void test_class() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(5);
+ }
+
+ // class C {};
+ // void main() {
+ // try {
+ // foo();
+ // } catch (C & e) {
+ // }
+ // }
+ public void test_class_ref() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class C {};
+ // void main() {
+ // try {
+ // foo();
+ // } catch (C * e) {
+ // }
+ // }
+ public void test_class_point() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // typedef int A;
+ // void main() {
+ // try {
+ // foo();
+ // } catch (A e) {
+ // }
+ // }
+ public void test_int_typedef() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // typedef int A;
+ // typedef A B;
+ // void main() {
+ // try {
+ // foo();
+ // } catch (B e) {
+ // }
+ // }
+ public void test_int_typedef2() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // void main() {
+ // try {
+ // foo();
+ // } catch (C e) {
+ // }
+ // }
+ public void test_class_unknown() throws Exception {
+ setPreferenceValue(CatchByReference.ER_ID, CatchByReference.PARAM_UNKNOWN_TYPE, false);
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // void main() {
+ // try {
+ // foo();
+ // } catch (C e) {
+ // }
+ // }
+ public void test_class_unknown_on() throws Exception {
+ setPreferenceValue(CatchByReference.ER_ID, CatchByReference.PARAM_UNKNOWN_TYPE, true);
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(4);
+ }
+
+ // class C {};
+ // typedef C B;
+ // void main() {
+ // try {
+ // foo();
+ // } catch (B e) {
+ // }
+ // }
+ public void test_class_typedef() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(6);
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java
new file mode 100644
index 00000000000..5cd0fa13aa1
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java
@@ -0,0 +1,650 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Anton Gorenkov and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anton Gorenkov - initial implementation
+ * Marc-Andre Laperle
+ * Nathan Ridge
+ * Danny Ferreira
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.cdt.codan.internal.checkers.ClassMembersInitializationChecker;
+
+/**
+ * Test for {@see ClassMembersInitializationChecker} class
+ */
+public class ClassMembersInitializationCheckerTest extends CheckerTestCase {
+ @Override
+ public boolean isCpp() {
+ return true;
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems(ClassMembersInitializationChecker.ER_ID);
+ }
+
+ private void disableSkipConstructorsWithFCalls() {
+ setPreferenceValue(ClassMembersInitializationChecker.ER_ID, ClassMembersInitializationChecker.PARAM_SKIP, false);
+ }
+
+ public void checkMultiErrorsOnLine(int line, int count) {
+ for (int i = 0; i < count; ++i) {
+ checkErrorLine(line);
+ }
+ assertEquals(count, markers.length);
+ }
+
+ // class C {
+ // int m;
+ // C() : m(0) {} // No warnings.
+ // };
+ public void testInitializationListShouldBeChecked() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class C {
+ // int m;
+ // C() { m = 0; } // No warnings.
+ // };
+ public void testAssignmentsInConstructorShouldBeChecked() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class C {
+ // int m;
+ // unsigned int ui;
+ // float f;
+ // double d;
+ // bool b;
+ // char c;
+ // long l;
+ // C() {} // 7 warnings for: m, ui, f, d, b, c, l.
+ // };
+ public void testBasicTypesShouldBeInitialized() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkMultiErrorsOnLine(9, 7);
+ }
+
+ // class Value {};
+ // class C {
+ // int* i;
+ // Value* v;
+ // C() {} // 2 warnings for: i, v.
+ // }
+ public void testPointersShouldBeInitialized() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkMultiErrorsOnLine(5, 2);
+ }
+
+ // class Value {};
+ // class C {
+ // int& i;
+ // Value& v;
+ // C() {} // 2 warnings for: i, v.
+ // }
+ public void testReferencesShouldBeInitialized() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkMultiErrorsOnLine(5, 2);
+ }
+
+ // enum Enum { v1, v2 };
+ // class C {
+ // Enum e;
+ // C() {} // 1 warning for: e.
+ // }
+ public void testEnumsShouldBeInitialized() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkMultiErrorsOnLine(4, 1);
+ }
+
+ // enum Enum { v1, v2 };
+ // class Value {};
+ // typedef int IntTypedef;
+ // typedef int* IntPtrTypedef;
+ // typedef int& IntRefTypedef;
+ // typedef Enum EnumTypedef;
+ // typedef Value ValueTypedef;
+ // class C {
+ // IntTypedef i;
+ // IntPtrTypedef ip;
+ // IntRefTypedef ir;
+ // EnumTypedef e;
+ // ValueTypedef v;
+ // C() {} // 5 warnings for: i, ip, ir, e.
+ // }
+ public void testTypedefsShouldBeInitialized() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkMultiErrorsOnLine(14, 4);
+ }
+
+ // class C {
+ // C() : i1(0) {} // 1 warning for: i2.
+ // C(int) : i2(0) {} // 1 warning for: i1.
+ // int i1, i2;
+ // };
+ public void testAFewConstructorsHandling() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(2, 3);
+ }
+
+ // template <typename T1, typename T2>
+ // class C {
+ // C() : i1(0), t1(T1()) {} // 1 warning for: i2.
+ // int i1, i2;
+ // T1 t1;
+ // T2 t2;
+ // };
+ public void testTemplateClassHandling() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(3);
+ }
+
+ // class C {
+ // template <typename T>
+ // C() : i1(0) {} // 1 warning for: i2.
+ // int i1, i2;
+ // };
+ public void testTemplateConstructorHandling() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(3);
+ }
+
+ // class C {
+ // C(); // No warnings.
+ // int i;
+ // };
+ public void testTemplateConstructorDeclarationOnlyHandling() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class C {
+ // C();
+ // int i1, i2;
+ // };
+ // C::C() : i1(0) {} // 1 warning for: i2.
+ public void testExternalConstructorHandling() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(5);
+ }
+
+ // template <typename T1, typename T2>
+ // class C {
+ // C();
+ // int i1, i2;
+ // T1 t1;
+ // T2 t2;
+ // };
+ // template <typename T1, typename T2>
+ // C<T1,T2>::C() : i1(0), t1(T1()) {} // 1 warning for: i2.
+ public void testExternalConstructorOfTemplateClassHandling() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(9);
+ }
+
+ // class C {
+ // template <typename T>
+ // C();
+ // int i1, i2;
+ // };
+ // template <typename T>
+ // C::C() : i1(0) {} // 1 warning for: i2.
+ public void testExternalTemplateConstructorHandling() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(7);
+ }
+
+ // template <typename T1, typename T2>
+ // class C {
+ // template <typename T>
+ // C();
+ // int i1, i2;
+ // T1 t1;
+ // T2 t2;
+ // };
+ // template <typename T1, typename T2>
+ // template <typename T>
+ // C<T1,T2>::C() : i1(0), t1(T1()) {} // 1 warning for: i2.
+ public void testExternalTemplateConstructorOfTemplateClassHandling() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(11);
+ }
+
+ // class C {
+ // class NestedC {
+ // NestedC() : i(0) {} // No warnings.
+ // int i;
+ // };
+ // C() {} // 1 warning for: i.
+ // int i;
+ // };
+ public void testNestedClassesHandling() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(6);
+ }
+
+ // class C {
+ // C() // 1 warning for: i.
+ // {
+ // class NestedC {
+ // NestedC() { i = 0; } // No warnings.
+ // int i;
+ // };
+ // }
+ // int i;
+ // };
+ public void testNestedClassInConstructorHandling() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(2);
+ }
+
+ // class C {
+ // C();
+ // int i;
+ // };
+ //
+ // C::C() // 1 warning for: i.
+ // {
+ // class NestedC { // No warnings.
+ // NestedC() { i = 0; }
+ // int i;
+ // };
+ // }
+ public void testNestedClassInExternalConstructorHandling() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(6);
+ }
+
+ // class C {
+ // C() // 1 warning for: i.
+ // {
+ // class NestedC {
+ // NestedC() { i = 0; } // No warnings.
+ // void C() { i = 0; } // No warnings.
+ // int i;
+ // };
+ // }
+ // int i;
+ // };
+ public void testNestedClassWithMethodNamedAsAnotherClassHandling() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(2);
+ }
+
+ // class C {
+ // C() {} // 1 warning for: i.
+ // int someFunction() { i = 0; } // No warnings.
+ // int i;
+ // };
+ public void testAssignmentIsNotInConstructor() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(2);
+ }
+
+ // class CBase {
+ // CBase() : i1(0) {} // No warnings.
+ // int i1;
+ // };
+ // class CDerived : public CBase {
+ // CDerived() : i2(0) {} // No warnings.
+ // int i2;
+ // };
+ public void testBaseClassMemberShouldNotBeTakenIntoAccount() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class C {
+ // C() {} // No warnings.
+ // static int i1, i2;
+ // };
+ // int C::i1 = 0;
+ // // NOTE: Static members are always initialized with 0, so there should not be warning on C::i2
+ // int C::i2;
+ public void testNoErrorsOnStaticMembers() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class C {
+ // public:
+ // C(const C& c) = delete;
+ // int i1, i2;
+ // };
+ public void testNoErrorsOnDeletedConstructor() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // void func(int & a) { a = 0; }
+ // class C {
+ // C() { func(i); } // No warnings.
+ // int i;
+ // };
+ public void testNoErrorsOnFunctionCallInitialization() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // void func(const int & a) {}
+ // class C {
+ // C() { func(i); } // 1 warning for: i.
+ // int i;
+ // };
+ public void testNoErrorsOnReadingFunctionCall() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(3);
+ }
+
+ // class C {
+ // C() { (i1) = 0; *&i2 = 0; } // No warnings.
+ // int i1, i2;
+ // };
+ public void testNoErrorsOnComplexAssignment() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class C {
+ // C() : i1(0) { // No warnings.
+ // i2 = i1;
+ // int someVar = 0;
+ // i3 = someVar;
+ // }
+ // int i1, i2, i3;
+ // };
+ public void testNoErrorsOnChainInitialization() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class A { protected: A(){} public: int a; }; // 1 warning for: a.
+ // class C: public A {
+ // C() {
+ // a = 1;
+ // }
+ // };
+ public void testErrorOnProtectedConstructor() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(1);
+ }
+
+ // struct S {
+ // int i;
+ // S() {} // 1 warning for: i.
+ // };
+ public void testCheckStructs() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(3);
+ }
+
+ // union U {
+ // int a;
+ // char b;
+ // U() { // No warnings.
+ // a=0;
+ // }
+ // };
+ public void testSkipUnions() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class C {
+ // int c;
+ // };
+ public void testNoErrorsIfThereIsNoConstructorsDefined() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class C {
+ // int i;
+ // C(bool b) { // No warnings.
+ // if (b)
+ // i = 0;
+ // // else - 'i' will be not initialized
+ // }
+ // };
+ public void testNoErrorsIfMemberWasInitializedInOneOfTheIfBranch() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class A {
+ // int a;
+ // A(int a) { setA(a); } // No warnings.
+ // A() { getA(); } // 1 warning for: a.
+ // void setA(int a) {
+ // this->a = a;
+ // }
+ // int getA() const {
+ // return a;
+ // }
+ // };
+ public void testUsingMethodsInConstructorWithPreference() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(4);
+ }
+
+ // class A;
+ // void initializeA1(A*);
+ // void initializeA2(A**);
+ // void initializeA3(A&);
+ //
+ // class A {
+ // int a;
+ // A() { initializeA1(this); } // No warnings.
+ // A(int a) { initializeA2(&this); } // No warnings.
+ // A(float a) { initializeA3(*this); } // No warnings.
+ // A(double a) { initializeA3(*(this)); } // No warnings.
+ // };
+ public void testUsingConstMethodsInConstructorWithPreference() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+
+ // class A {
+ // int a;
+ // A(int a) { setA(a); } // 1 warning for: a.
+ // A() { getA(); } // 1 warning for: a.
+ // void setA(int a) {
+ // this->a = a;
+ // }
+ // int getA() const {
+ // return a;
+ // }
+ // };
+ public void testUsingMethodsInConstructorWithoutPreference() throws Exception {
+ disableSkipConstructorsWithFCalls();
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(3,4);
+ }
+
+ // class A;
+ // void initializeA1(A*);
+ // void initializeA2(A**);
+ // void initializeA3(A&);
+ //
+ // class A {
+ // int a;
+ // A() { initializeA1(this); } // 1 warning for: a.
+ // A(int a) { initializeA2(&this); } // 1 warning for: a.
+ // A(float a) { initializeA3(*this); } // 1 warning for: a.
+ // A(double a) { initializeA3(*(this)); } // 1 warning for: a.
+ // };
+ public void testUsingConstMethodsInConstructorWithoutPreference() throws Exception {
+ disableSkipConstructorsWithFCalls();
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(8,9,10,11);
+ }
+
+ // @file:test.h
+ // class C {
+ // int field;
+ // C();
+ // void initObject();
+ //};
+
+ // @file:test.cpp
+ // #include "test.h"
+ // C::C() {
+ // initObject();
+ // }
+ public void testMethodDeclarationInOtherFile_368419() throws Exception {
+ CharSequence[] code = getContents(2);
+ loadcode(code[0].toString());
+ loadcode(code[1].toString());
+ runOnProject();
+ checkNoErrors();
+ }
+
+ //class D {
+ // int field;
+ // D(const D& toBeCopied) {
+ // *this = toBeCopied;
+ // };
+ //};
+ public void testAssignThis_368420() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ //class D {
+ // int field;
+ // D(const D& toBeCopied) {
+ // *(&(*this)) = toBeCopied;
+ // };
+ //};
+ public void testAssignThisUnaryExpressions_368420() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ //class D {
+ // int field;
+ // D(const D& toBeCopied) {
+ // this = toBeCopied;
+ // };
+ //};
+ public void testAssignThisNonLValue_368420() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(3);
+ }
+
+ //class D {
+ // int field;
+ // D();
+ // D(const D& toBeCopied) {
+ // D temp;
+ // temp = *(&(*this)) = toBeCopied;
+ // };
+ //};
+ public void testAssignThisMultiBinaryExpressions_368420() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ //@file:test.h
+ //template <typename>
+ //struct B;
+
+ //@file:test.cpp
+ //#include "test.h"
+ //
+ //template <typename>
+ //struct A {
+ //};
+ //
+ //template <typename valueT>
+ //struct B<A<valueT> > {
+ // const A<valueT>& obj;
+ // B(const A<valueT>& o) : obj(o) {}
+ //};
+ public void testTemplatePartialSpecialization_368611() throws Exception {
+ CharSequence[] code = getContents(2);
+ loadcode(code[0].toString());
+ loadcode(code[1].toString());
+ runOnProject();
+ checkNoErrors();
+ }
+
+ // struct S {
+ // int i;
+ // S() = default;
+ // };
+ public void testDefaultConstructor_365498() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ }
+
+ // struct S {
+ // int i;
+ //
+ // S(S&) = default;
+ // S(const S&) = default;
+ // S(volatile S&) = default;
+ // S(const volatile S&) = default;
+ // S(S&&) = default;
+ // S(const S&&) = default;
+ // S(volatile S&&) = default;
+ // S(const volatile S&&) = default;
+ // };
+ public void testDefaultCopyOrMoveConstructor_395018() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // template <typename T>
+ // struct S {
+ // int i;
+ //
+ // S(const S&) = default;
+ // S(S&&) = default;
+ // };
+ public void testDefaultCopyOrMoveConstructorInTemplate_408303() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // struct A {
+ // A(int n) : waldo(n) {}
+ // A() : A(42) {}
+ // int waldo;
+ // };
+ public void testDelegatingConstructor_402607() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // struct A {
+ // typedef A B;
+ // A(int n) : waldo(n) {}
+ // A() : B(42) {}
+ // int waldo;
+ // };
+ public void testDelegatingConstructorTypedef_402607() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // struct A {
+ // A() {};
+ // int x = 0;
+ // };
+ public void testNonstaticDataMemberInitializer_400673() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CommentCheckerLineTests.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CommentCheckerLineTests.java
new file mode 100644
index 00000000000..59e438128b9
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CommentCheckerLineTests.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2015 QNX Software System and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Elena Laskavaia (QNX Software System) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import java.io.File;
+
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.cdt.codan.internal.checkers.CommentChecker;
+import org.junit.Test;
+
+/**
+ * Tests for CommentChecker
+ */
+public class CommentCheckerLineTests extends CheckerTestCase {
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems(CommentChecker.COMMENT_NO_LINE);
+ }
+
+ // void foo() {
+ // return; // error
+ // }
+ @Test
+ public void testLineComment() throws Exception {
+ checkSampleAbove();
+ }
+
+ // void foo() {
+ // return;
+ // }
+ @Test
+ public void testNoLineComment() throws Exception {
+ checkSampleAbove();
+ }
+
+ // char * foo() {
+ // return "// this is a string";
+ // }
+ @Test
+ public void testNoLineCommentInString() throws Exception {
+ checkSampleAbove();
+ }
+
+ // void foo() {
+ // return; // not an error in c++
+ // }
+ @Test
+ public void testLineCommentCpp() throws Exception {
+ checkSampleAboveCpp();
+ }
+
+ // #define AAA // error even in prepro
+ @Test
+ public void testLineCommentInPrepro() throws Exception {
+ checkSampleAbove();
+ }
+
+ // @file:test.h
+ // int foo();// error too
+
+
+ // @file:test.c
+ // #include "test.h"
+ // int bar() {
+ // foo();
+ // }
+ public void testHeader() throws Exception {
+ loadcode(getContents(2));
+ runOnProject();
+ checkErrorLine(new File("test.h"), 1); //$NON-NLS-1$
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CommentCheckerNestedTests.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CommentCheckerNestedTests.java
new file mode 100644
index 00000000000..ea95da3d0f0
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CommentCheckerNestedTests.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2015 QNX Software System and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Elena Laskavaia (QNX Software System) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.cdt.codan.internal.checkers.CommentChecker;
+import org.junit.Test;
+
+/**
+ * Tests for CommentChecker
+ */
+public class CommentCheckerNestedTests extends CheckerTestCase {
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems(CommentChecker.COMMENT_NO_START);
+ }
+
+ // void foo() {
+ // return; /* /* */ // error
+ // }
+ @Test
+ public void testLineComment() throws Exception {
+ checkSampleAbove();
+ }
+ // void foo() {
+ // return; /*
+ // /* // error
+ // */
+ // }
+ @Test
+ public void testLineComment2() throws Exception {
+ checkSampleAbove();
+ }
+
+ // void foo() {
+ // return; /* */
+ // }
+ @Test
+ public void testNoLineComment() throws Exception {
+ checkSampleAbove();
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/FormatStringCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/FormatStringCheckerTest.java
new file mode 100644
index 00000000000..e4e13476dc2
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/FormatStringCheckerTest.java
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 Meisam Fathi and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Meisam Fathi - base API
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+
+/**
+ * Test for {@see FormatStringChecker} class
+ */
+public class FormatStringCheckerTest extends CheckerTestCase {
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems("org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem"); //$NON-NLS-1$
+ }
+
+ // int f(){
+ // return 0;
+ // }
+ public void testBase() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // int f(){
+ // char inputstr[5];
+ // scanf("%s", inputstr); // here
+ // return 0;
+ // }
+ public void testSimple() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ }
+
+ // int main(void) {
+ // char inputstr1[5];
+ // int inputval;
+ // int i = 5;
+ // scanf("%i %4s", inputval, inputstr1); // no error here
+ // printf("%d" ,i);
+ // return 0;
+ // }
+ public void testIntRight() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // int main(void) {
+ // char inputstr[5];
+ // int inputval;
+ // int i = 5;
+ // scanf("%d %9s", inputval, inputstr);
+ // printf("%d" ,i);
+ // return 0;
+ // }
+ public void testIntWrong() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(5);
+ }
+
+ // int main(void) {
+ // char inputstr1[5];
+ // int inputval;
+ // int i = 5;
+ // scanf("%4s %i", inputstr1, inputval);
+ // printf("%d" ,i);
+ // return 0;
+ // }
+ public void testRightInt() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // int main(void) {
+ // char inputstr1[5];
+ // char inputstr2[5];
+ // int i = 5;
+ // scanf("%4s %9s", inputstr1, inputstr2);
+ // printf("%d" ,i);
+ // return 0;
+ // }
+ public void testRightWrong() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(5);
+ }
+
+ // int main(void) {
+ // char inputstr1[5];
+ // int inputval;
+ // int i = 5;
+ // scanf("%9s %i", inputstr1, inputval);
+ // printf("%d" ,i);
+ // return 0;
+ // }
+ public void testWrongInt() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(5);
+ }
+
+ // int main(void) {
+ // char inputstr1[5];
+ // char inputstr2[5];
+ // int i = 5;
+ // scanf("%9s %4s", inputstr1, inputstr2);
+ // printf("%d" ,i);
+ // return 0;
+ // }
+ public void testWrongRight() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(5);
+ }
+
+ // int main(void) {
+ // char inputstr[5];
+ // int i = 5;
+ // scanf("%s", inputstr);
+ // printf("%d" ,i);
+ // return 0;
+ // }
+ public void testInfiniteSize() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(4);
+ }
+
+ // int main(void) {
+ // puts("Enter a string whose length is bellow 5:");
+ // char inputstr[5];
+ // int i = 5;
+ // scanf("%3s", inputstr);
+ // printf("%d" ,i);
+ // return 0;
+ // }
+ public void testRight() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // int main(void) {
+ // char inputstr1[5];
+ // char inputstr2[5];
+ // int i = 5;
+ // scanf("%3s %4s", inputstr1, inputstr2);
+ // printf("%d" ,i);
+ // return 0;
+ // }
+ public void testRightRight() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // int main(void) {
+ // char inputstr1[5];
+ // char inputstr2[5];
+ // int i = 5;
+ // scanf("%8s %9s", inputstr1, inputstr2);
+ // printf("%d" ,i);
+ // return 0;
+ // }
+ public void testWrongWrong() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(5);
+ }
+
+ // char inputstr[5];
+ // int foo(void){
+ // char inputstr[15];
+ // return 0;
+ // }
+ // int main(void) {
+ // puts("Enter a string whose length is bellow 5:");
+ // int i = 5;
+ // scanf("%10s", inputstr);
+ // printf("%d" ,i);
+ // return 0;
+ // }
+ public void testGlobalBeforeWrong() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(9);
+ }
+
+ // int main(void) {
+ // puts("Enter a string whose length is bellow 5:");
+ // char inputstr[15];
+ // int i = 5;
+ // scanf("%10s", inputstr);
+ // printf("%d" ,i);
+ // return 0;
+ // }
+ // int foo(void){
+ // char inputstr[5];
+ // return 0;
+ // }
+ public void testNonglobalAfterRight() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // int main(void) {
+ // char inputstr[5];
+ // int i = 5;
+ // scanf("%10s", inputstr);
+ // printf("%d" ,i);
+ // return EXIT_SUCCESS;
+ // }
+ // int foo(void){
+ // char inputstr[15];
+ // return 0;
+ // }
+ public void testNonglobalAfterWrong() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(4);
+ }
+
+ // int foo(void){
+ // char inputstr[5];
+ // return 0;
+ // }
+ // int main(void) {
+ // char inputstr[15];
+ // int i = 5;
+ // scanf("%10s", inputstr);
+ // printf("%d" ,i);
+ // return 0;
+ // }
+ public void testNonglobalBeforeRight() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // int foo(void){
+ // char inputstr[15];
+ // return 0;
+ // }
+ // int main(void) {
+ // char inputstr[5];
+ // int i = 5;
+ // scanf("%10s", inputstr);
+ // printf("%d" ,i);
+ // return 0;
+ // }
+ public void testNonglobalBeforeWrong() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(8);
+ }
+
+ // int main(void) {
+ // char inputstr1[5];
+ // int inputval;
+ // int i = 5;
+ // scanf("%i %as", inputval, inputstr1); // no error here
+ // printf("%d" ,i);
+ // return 0;
+ // }
+ public void testGaurdedRight() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+} \ No newline at end of file
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/NonVirtualDestructorCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/NonVirtualDestructorCheckerTest.java
new file mode 100644
index 00000000000..6949d3f09a4
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/NonVirtualDestructorCheckerTest.java
@@ -0,0 +1,221 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 Patrick Hofer and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Patrick Hofer - Initial API and implementation
+ * Tomasz Wesolowski
+ * Sergey Prigogin (Google)
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructor;
+import org.eclipse.core.resources.IMarker;
+
+/**
+ * Test for {@link NonVirtualDestructor} class.
+ */
+public class NonVirtualDestructorCheckerTest extends CheckerTestCase {
+ @Override
+ public boolean isCpp() {
+ return true;
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems(NonVirtualDestructor.PROBLEM_ID);
+ }
+
+ // struct A {
+ // virtual void f() = 0;
+ // virtual ~A(); // ok.
+ // };
+ public void testVirtualDtorInClass() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // struct A {
+ // virtual void f() = 0;
+ // protected:
+ // ~A(); // ok.
+ // };
+ public void testNonPublicVirtualDtorInClass() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // struct A {
+ // virtual void f() { };
+ // ~A(); // warn! public non-virtual dtor.
+ // };
+ public void testPublicVirtualDtorInClass() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(3);
+ }
+
+ // struct A {
+ // virtual void f() { };
+ // // warn! implicit public non-virtual dtor.
+ // };
+ public void testImplicitPublicNonVirtualDtorInClass() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(1);
+ }
+
+ // struct F { };
+ //
+ // struct A {
+ // virtual void f() { };
+ // private:
+ // friend class F;
+ // ~A(); // warn! can be called from class F.
+ // };
+ public void testPublicNonVirtualDtorCanBeCalledFromFriendClass() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(7);
+ }
+
+ // struct A {
+ // virtual void f() { };
+ // virtual ~A();
+ // };
+ //
+ // struct B {
+ // ~B(); // ok.
+ // };
+ public void testVirtualDtorInBaseClass1() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // struct A {
+ // virtual void f() { };
+ // virtual ~A(); // ok.
+ // };
+ //
+ // struct B : public A { };
+ //
+ // struct C { };
+ //
+ // struct D : public B, C { };
+ //
+ // struct E : public D { };
+ public void testVirtualDtorInBaseClass2() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class A {
+ // public:
+ // virtual ~A();
+ // };
+ //
+ // class B : public A {
+ // public:
+ // ~B();
+ // virtual void m();
+ // friend class C;
+ // };
+ public void testVirtualDtorInBaseClass3() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // struct A {
+ // virtual void f() { };
+ // ~A(); // warn! public non-virtual dtor.
+ // // this affects B, D and E further down in the hierarchy as well
+ // };
+ //
+ // struct B : public A { };
+ //
+ // struct C { };
+ //
+ // struct D : public B, C { };
+ //
+ // struct E : public D {
+ // };
+ public void testNonVirtualDtorInBaseClass() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(3, 7, 11, 13);
+ }
+
+ // class A {
+ // virtual void f1() { };
+ // virtual void f2() = 0;
+ // };
+ //
+ // class B : public A {
+ // virtual void f1() { };
+ // virtual void f2() { };
+ // virtual ~B();
+ // };
+ public void testAbstractBaseClass() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ // It doesn't matter if the class is abstract or not - dtor can be called polymorphically.
+ checkErrorLines(1);
+ }
+
+ // struct Base {
+ // };
+ // struct Derived : Base {
+ // virtual void bar();
+ // };
+ public void testImplicitDtorInBaseClass() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(3);
+ }
+
+ // struct Base {
+ // ~Base();
+ // };
+ // struct Derived : Base {
+ // virtual void bar();
+ // };
+ public void testExplicitDtorInBaseClass() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(4);
+ }
+
+ // class C : public C {};
+ public void testBug368446_stackOverflow() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class B;
+ // class A : public B {};
+ // class B : public A {};
+ public void testBug368446_stackOverflow_indirect() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class Foo {
+ // virtual void bar();
+ // };
+ public void testBug372009_wrongClassNameInMessage() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ assertMessageContains("Foo", markers[0]);
+ }
+
+ // class Foo {
+ // virtual void bar();
+ // };
+ public void testBug496628_MarkerBounds() throws Exception {
+ String code = getAboveComment();
+ loadCodeAndRun(code);
+ IMarker marker = checkErrorLine(1);
+ int start = marker.getAttribute(IMarker.CHAR_START, -1);
+ int end = marker.getAttribute(IMarker.CHAR_END, -1);
+ // The error should not cover the entire class
+ assertTrue((start == -1 && end == -1) || // ok, not multi-line
+ !code.substring(start, end).contains("\n"));
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/ProblemBindingCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/ProblemBindingCheckerTest.java
new file mode 100644
index 00000000000..149785324d9
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/ProblemBindingCheckerTest.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2015 Marc-Andre Laperle and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc-Andre Laperle - Initial API and implementation
+ * Sergey Prigogin (Google)
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.cdt.codan.internal.checkers.ProblemBindingChecker;
+import org.eclipse.core.resources.IMarker;
+
+public class ProblemBindingCheckerTest extends CheckerTestCase {
+ @Override
+ public boolean isCpp() {
+ return true;
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems(
+ ProblemBindingChecker.ERR_ID_AmbiguousProblem, ProblemBindingChecker.ERR_ID_Candidates,
+ ProblemBindingChecker.ERR_ID_CircularReferenceProblem, ProblemBindingChecker.ERR_ID_FieldResolutionProblem,
+ ProblemBindingChecker.ERR_ID_FunctionResolutionProblem, ProblemBindingChecker.ERR_ID_InvalidArguments,
+ ProblemBindingChecker.ERR_ID_InvalidTemplateArgumentsProblem, ProblemBindingChecker.ERR_ID_LabelStatementNotFoundProblem,
+ ProblemBindingChecker.ERR_ID_MemberDeclarationNotFoundProblem, ProblemBindingChecker.ERR_ID_MethodResolutionProblem,
+ ProblemBindingChecker.ERR_ID_OverloadProblem, ProblemBindingChecker.ERR_ID_RedeclarationProblem,
+ ProblemBindingChecker.ERR_ID_RedefinitionProblem, ProblemBindingChecker.ERR_ID_TypeResolutionProblem,
+ ProblemBindingChecker.ERR_ID_VariableResolutionProblem);
+ }
+
+ // int main () {
+ // struct X {} x;
+ // fun(x.y);
+ // }
+ public void testFieldInFunctionCall_338683() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3, ProblemBindingChecker.ERR_ID_FieldResolutionProblem);
+ }
+
+ // struct A {
+ // A(int x, int y);
+ // };
+ //
+ // void test() {
+ // A a("hi", 1, 2);
+ // }
+ public void testImplicitConstructorCall_404774() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(6, ProblemBindingChecker.ERR_ID_InvalidArguments);
+ }
+
+ // int main () {
+ // struct X {} x;
+ // x.b(
+ // x.y(),
+ // x.y(
+ // x.y),
+ // x.y(
+ // x.y(
+ // a,
+ // fun(
+ // x.b(),
+ // x.y,
+ // a.b()))));
+ // }
+ public void testVariousFieldMethodCombinations_338683() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3, ProblemBindingChecker.ERR_ID_MethodResolutionProblem);
+ checkErrorLine(4, ProblemBindingChecker.ERR_ID_MethodResolutionProblem);
+ checkErrorLine(5, ProblemBindingChecker.ERR_ID_MethodResolutionProblem);
+ checkErrorLine(6, ProblemBindingChecker.ERR_ID_FieldResolutionProblem);
+ checkErrorLine(7, ProblemBindingChecker.ERR_ID_MethodResolutionProblem);
+ checkErrorLine(8, ProblemBindingChecker.ERR_ID_MethodResolutionProblem);
+ checkErrorLine(9, ProblemBindingChecker.ERR_ID_VariableResolutionProblem);
+ checkErrorLine(10, ProblemBindingChecker.ERR_ID_FunctionResolutionProblem);
+ checkErrorLine(11, ProblemBindingChecker.ERR_ID_MethodResolutionProblem);
+ checkErrorLine(12, ProblemBindingChecker.ERR_ID_FieldResolutionProblem);
+ checkErrorLine(13, ProblemBindingChecker.ERR_ID_MethodResolutionProblem);
+ }
+
+ // #define MACRO(code) code
+ // int main() {
+ // MACRO(foo());
+ // return 0;
+ // }
+ public void testDontUnderlineWholeMacro_341089() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ IMarker marker = checkErrorLine(3, ProblemBindingChecker.ERR_ID_FunctionResolutionProblem);
+ assertFalse(marker.getAttribute(IMarker.MESSAGE, "").contains("MACRO"));
+ }
+
+ // auto d = 42_waldo;
+ public void testNonexistentUDLOperator_484619() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(1, ProblemBindingChecker.ERR_ID_FunctionResolutionProblem);
+ }
+
+ // struct R {};
+ // R operator "" _waldo(const char*, unsigned long); // expects a string literal
+ // auto d = 42_waldo; // passing an integer
+ public void testUDLOperatorWithWrongType_484619() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3, ProblemBindingChecker.ERR_ID_InvalidArguments);
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java
new file mode 100644
index 00000000000..69715f65a74
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java
@@ -0,0 +1,451 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2015 Alena Laskavaia
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alena Laskavaia - initial API and implementation
+ * Felipe Martinez - ReturnCheckerTest implementation
+ * Tomasz Wesolowski - Bug 348387
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import org.eclipse.cdt.codan.core.param.IProblemPreference;
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.cdt.codan.internal.checkers.ReturnChecker;
+
+/**
+ * Test for {@see ReturnCheckerTest} class
+ */
+public class ReturnCheckerTest extends CheckerTestCase {
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems(ReturnChecker.RET_NORET_ID,ReturnChecker.RET_ERR_VALUE_ID,ReturnChecker.RET_NO_VALUE_ID);
+ }
+
+ // dummy() {
+ // return; // no error here on line 2
+ // }
+ public void testDummyFunction() throws Exception {
+ checkSampleAbove();
+ // because return type if not defined, usually people don't care
+ }
+
+ // void void_function(void) {
+ // return; // no error here
+ // }
+ public void testVoidFunction() throws Exception {
+ checkSampleAbove();
+ }
+
+ // int integer_return_function(void) { // error
+ // if (global) {
+ // if (global == 100) {
+ // return; // error here on line 4
+ // }
+ // }
+ // }
+ public void testBasicTypeFunction() throws Exception {
+ checkSampleAbove();
+ }
+
+ //
+ // struct My_Struct {
+ // int a;
+ // };
+ //
+ // struct My_Struct struct_return_function(void) {
+ // return; // error here on line 6
+ // }
+ public void testUserDefinedFunction() throws Exception {
+ checkSampleAbove();
+ }
+
+ // typedef unsigned int uint8_t;
+ //
+ // uint8_t return_typedef(void) {
+ // return; // error here on line 4
+ // }
+ public void testTypedefReturnFunction() throws Exception {
+ checkSampleAbove();
+ }
+
+
+ // typedef unsigned int uint8_t;
+ //
+ // uint8_t (*return_fp_no_typedef(void))(void)
+ // {
+ // return; // error here on line 5
+ // }
+ public void testFunctionPointerReturnFunction() throws Exception {
+ checkSampleAbove();
+ }
+
+ // void test() {
+ // class A {
+ // public:
+ // void m() {
+ // return; // should not be an error here
+ // }
+ // };
+ // }
+ public void testInnerFunction_Bug315525() throws Exception {
+ checkSampleAbove();
+ }
+
+ // void test() {
+ // class A {
+ // public:
+ // int m() {
+ // return; // error here
+ // }
+ // };
+ // }
+ public void testInnerFunction_Bug316154() throws Exception {
+ checkSampleAbove();
+ }
+
+ // class c {
+ // c() {
+ // return 0;
+ // }
+ //
+ // ~c() {
+ // return;
+ // }
+ // };
+ public void testConstructorRetValue() throws Exception {
+ loadCodeAndRunCpp(getAboveComment());
+ checkErrorLine(3, ReturnChecker.RET_ERR_VALUE_ID);
+ }
+
+ // class c {
+ // c() {
+ // return;
+ // }
+ //
+ // ~c() {
+ // return;
+ // }
+ // };
+ public void testConstructor_Bug323602() throws Exception {
+ IProblemPreference macro = getPreference(ReturnChecker.RET_NO_VALUE_ID, ReturnChecker.PARAM_IMPLICIT);
+ macro.setValue(Boolean.TRUE);
+ loadCodeAndRunCpp(getAboveComment());
+ checkNoErrors();
+ }
+
+ // void f()
+ // {
+ // [](int r){return r;}(5);
+ // }
+ public void testLambda_Bug332285() throws Exception {
+ checkSampleAbove();
+ }
+// void f()
+// {
+// if ([](int r){return r == 0;}(0))
+// ;
+// }
+ public void testLambda2_Bug332285() throws Exception {
+ checkSampleAbove();
+ }
+
+ // void g()
+ // {
+ // int r;
+ // ({return r;}); // error
+ // }
+ public void testGccExtensions() throws Exception {
+ checkSampleAbove();
+ }
+
+ // auto f() -> void
+ // {
+ // }
+ public void testVoidLateSpecifiedReturnType_Bug337677() throws Exception {
+ checkSampleAboveCpp();
+ }
+
+ // auto f() -> void* // error
+ // {
+ // }
+ public void testVoidPointerLateSpecifiedReturnType_Bug337677() throws Exception {
+ checkSampleAboveCpp();
+ }
+
+// int f() // error
+// {
+// if (g())
+// h();
+// else
+// return 0;
+// }
+ public void testBranches_Bug342906() throws Exception {
+ checkSampleAbove();
+ }
+
+// int f() // error
+// {
+// switch (g()) {
+// case 1: h(); break;
+// case 2:
+// return 0;
+// }
+ public void testSwitch() throws Exception {
+ checkSampleAbove();
+ }
+
+ //int bar(int foo)
+ //{
+ // if(foo)
+ // return 0;
+ // else
+ // return 0;
+ //}
+ public void testBranches_Bug343767() throws Exception {
+ checkSampleAbove();
+ }
+
+ //int bar(int foo)
+ //{
+ // if(foo)
+ // return 0;
+ // else
+ // return 0;
+ // foo++;
+ //}
+ public void testBranchesDeadCode_Bug343767() throws Exception {
+ checkSampleAbove();
+ }
+
+// int f() // error
+// {
+// switch (g()) {
+// case 1: return 1;
+// case 2: return 0;
+// }
+// }
+ public void testBranchesSwitch_Bug343767a() throws Exception {
+ checkSampleAbove();
+ }
+// int f()
+// {
+// switch (g()) {
+// case 1: return 1;
+// case 2: return 0;
+// default: return -1;
+// }
+// }
+ public void testBranchesSwitch_Bug343767b() throws Exception {
+ checkSampleAbove();
+ }
+ //int bar(int foo)
+ //{
+ // if(foo)
+ // return 0;
+ // else
+ // if (g()) return 0;
+ // else return 1;
+ //}
+ public void testBranches2_Bug343767() throws Exception {
+ checkSampleAbove();
+ }
+ //int bar(int foo) // error
+ //{
+ // while(foo) {
+ // return 0;
+ // }
+ //}
+ public void testWhile() throws Exception {
+ checkSampleAbove();
+ }
+
+ // int f345687() {
+ // {
+ // return 0;
+ // }
+ // }
+ public void testNextedBlock_Bug345687() throws Exception {
+ checkSampleAbove();
+ }
+
+ // int
+ // fp_goto(int a)
+ // {
+ // if (a) {
+ // goto end;
+ // }
+ // end:
+ // return (a);
+ // }
+ public void testGoto_Bug346559() throws Exception {
+ checkSampleAbove();
+ }
+
+ // int main()
+ // {
+ // char c; // added so function body is non-empty
+ // // no error since return value in main is optional
+ // }
+ public void testMainFunction() throws Exception {
+ checkSampleAbove();
+ }
+
+ // #include <vector>
+ // std::vector<int> f() {
+ // return {1,2,3};
+ // }
+ public void testReturnInitializerList() throws Exception {
+ checkSampleAbove();
+ }
+
+ // void f() __attribute__((noreturn));
+ //
+ // int test() {
+ // f();
+ // }
+ public void testNoReturn() throws Exception {
+ checkSampleAbove();
+ }
+
+ // struct A {
+ // A();
+ // ~A() __attribute__((noreturn));
+ // };
+ //
+ // int test() {
+ // A();
+ // }
+ public void testNoReturnInDestructor_461538() throws Exception {
+ checkSampleAboveCpp();
+ }
+
+ // int try1() {
+ // try {
+ // return 5;
+ // } catch (...) {
+ // return 5;
+ // }
+ // }
+ public void testTryBlock1() throws Exception {
+ // bug 348387
+ checkSampleAboveCpp();
+ }
+
+ // int try2() { // error
+ // try {
+ // return 5;
+ // } catch (int) {
+ // }
+ // }
+ public void testTryBlock2() throws Exception {
+ checkSampleAboveCpp();
+ }
+
+ // int try3() { // error
+ // try {
+ // } catch (int a) {
+ // return 5;
+ // }
+ // }
+ public void testTryBlock3() throws Exception {
+ checkSampleAboveCpp();
+ }
+
+ // int retindead() {
+ // return 5;
+ // ;
+ // }
+ public void testRetInDeadCode1() throws Exception {
+ // bug 348386
+ checkSampleAbove();
+ }
+
+ // int retindead() {
+ // throw 42;
+ // ;
+ // }
+ public void testRetInDeadCodeThrow() throws Exception {
+ // bug 356908
+ checkSampleAboveCpp();
+ }
+
+// bool func( int i )
+// {
+// switch( i )
+// {
+// case 0:
+// return true;
+// default:
+// return false;
+// break;
+// }
+// }
+ public void testRetInDeadCodeCase() throws Exception {
+ // Bug 350168
+ checkSampleAboveCpp();
+ }
+
+// int test1() {
+// do {
+// return 1;
+// } while (0);
+// }
+ public void testNoRetInfinitLoop() throws Exception {
+ // Bug 394521
+ checkSampleAbove();
+ }
+
+// int test1_f() // WARNING HERE: "No return, in function returning non-void"
+// {
+// while (1)
+// {
+// }
+// }
+ public void testNoRetInfinitLoop2() throws Exception {
+ // Bug 394521
+ checkSampleAboveCpp();
+ }
+
+ // int foo() { // error
+ // int waldo = waldo();
+ // if (waldo);
+ // }
+ public void testSelfReferencingVariable_452325() throws Exception {
+ // Just check that codan runs without any exceptions being thrown.
+ checkSampleAboveCpp();
+ }
+
+ // int bar(int x) { return x; }
+ // int foo() { // error
+ // int waldo = bar(waldo);
+ // if (bar(waldo));
+ // }
+ public void testSelfReferencingVariable_479638() throws Exception {
+ // Just check that codan runs without any exceptions being thrown.
+ checkSampleAboveCpp();
+ }
+
+ // int foo(int x) { // error
+ // switch (x) {
+ // }
+ // }
+ public void testEmptySwitch_455828() throws Exception {
+ checkSampleAbove();
+ }
+
+ // int foo(int x) { // error
+ // switch (x) {
+ // case 0:
+ // return 42;;
+ // default:
+ // }
+ // }
+ public void testDoubleSemicolonInSwitchCase_455828() throws Exception {
+ checkSampleAboveCpp();
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnStyleCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnStyleCheckerTest.java
new file mode 100644
index 00000000000..b28128afe53
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnStyleCheckerTest.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 Marc-Andre Laperle and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc-Andre Laperle - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+
+public class ReturnStyleCheckerTest extends CheckerTestCase {
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems("org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem"); //$NON-NLS-1$
+ }
+
+ // void foo() {
+ // return; // no error
+ // }
+ public void testSimpleReturn() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // void foo() {
+ // return
+ // ; // no error
+ // }
+ public void testSimpleReturnMultiLine() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // int foo() {
+ // return(0); // no error
+ // }
+ public void testSimpleReturnValue() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // int foo() {
+ // return 0; // error line 2
+ // }
+ public void testSimpleReturnValueError() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(2);
+ }
+
+ // int foo() {
+ // return // no error
+ // (
+ // 0
+ // );
+ // }
+ public void testReturnValueMultiline() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // int foo() {
+ // return // error line 2
+ // 0
+ // ;
+ // }
+ public void testReturnValueMultilineError() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(2);
+ }
+
+ // int foo() {
+ // return ((0));// no error
+ // }
+ public void testReturnValueMultipleBrackets() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // int foo() {
+ // return // no error
+ // (
+ // (0)
+ // );
+ // }
+ public void testReturnValueMultilineMultipleBrackets() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // #define MY_RETURN return(0);
+ //
+ // int foo() {
+ // MY_RETURN // no error
+ // }
+ public void testReturnDefine() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // #define MY_RETURN return 0;
+ //
+ // int foo() {
+ // MY_RETURN // error line 4
+ // }
+ public void testReturnDefineError() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(4);
+ }
+} \ No newline at end of file
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/StatementHasNoEffectCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/StatementHasNoEffectCheckerTest.java
new file mode 100644
index 00000000000..4859975b9b3
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/StatementHasNoEffectCheckerTest.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2015 Alena Laskavaia
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alena Laskavaia - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import java.io.File;
+
+import org.eclipse.cdt.codan.core.param.IProblemPreference;
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectChecker;
+import org.eclipse.core.resources.IMarker;
+
+/**
+ * Test for {@see StatementHasNoEffectChecker} class
+ */
+public class StatementHasNoEffectCheckerTest extends CheckerTestCase {
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems(StatementHasNoEffectChecker.ER_ID);
+ }
+
+ // main() {
+ // int a;
+ // +a; // error here on line 3
+ // }
+ public void testUnaryExpression() throws Exception {
+ checkSampleAbove();
+ }
+
+ // main() {
+ // int a,b;
+ //
+ // b+a; // error here on line 4
+ // }
+ public void testBinaryExpression() throws Exception {
+ checkSampleAbove();
+ }
+
+ // main() {
+ // int a,b;
+ //
+ // a=b+a; // no error here
+ // }
+ public void testNormalAssignment() throws Exception {
+ checkSampleAbove();
+ }
+
+ // main() {
+ // int a,b;
+ //
+ // (a=b); // no errors here
+ // a+=b;
+ // a<<=b;
+ // a-=b;
+ // a++;
+ // b--;
+ // --a;
+ // ++b;
+ // a%=2;
+ // a>>=2;
+ // }
+ public void testFalsePositives() throws Exception {
+ checkSampleAbove();
+ }
+
+ // main() {
+ // int a;
+ // a; // error here on line 3
+ // }
+ public void testIdExpression() throws Exception {
+ checkSampleAbove();
+ }
+
+ // main() {
+ // int a=({foo();a;}); // no error here on line 2
+ // char *p=({char s[]="Some string";&s[0];}); // no error here on line 3
+ // }
+ public void testGNUExpressionCompoundStmtFalsePositives() throws Exception {
+ checkSampleAbove();
+ }
+
+ // main() {
+ // int z=({int a=0; +a; a;}) // error here on line 2
+ // }
+ public void testGNUExpressionCompoundStmtInside() throws Exception {
+ checkSampleAbove();
+ }
+
+ // main() {
+ // int a;
+ // +a; // error here on line 3
+ // }
+
+ // foo() {
+ // int a;
+ //
+ // +a; // error here on line 4
+ // }
+ public void test2FilesUnaryExpression() throws Exception {
+ /* This test is using two files */
+ CharSequence[] code = getContents(2);
+ File f1 = loadcode(code[0].toString());
+ File f2 = loadcode(code[1].toString());
+ runOnProject();
+ checkErrorLine(f1, 3);
+ checkErrorLine(f2, 4);
+ }
+
+ // main() {
+ // for (a=b;a;a=a->next);
+ // }
+ public void testForTestExpression() throws Exception {
+ checkSampleAbove();
+ }
+
+ // void main() {
+ // bool a;
+ // class c {};
+ // c z;
+ // (a = z.foo(1)) || (a = z.foo(2));
+ // }
+ public void testLazyEvalHack() throws Exception {
+ checkSampleAboveCpp();
+ }
+
+ // main() {
+ // A a,b;
+ //
+ // b+=a; // no error here on line 4
+ // }
+ public void testOverloadedBinaryExpression() throws Exception {
+ checkSampleAboveCpp();
+ }
+
+ //#define FUNC(a) a
+ // main() {
+ // int a;
+ // FUNC(a); // error by default
+ // }
+ public void testInMacro() throws Exception {
+ IProblemPreference macro = getPreference(StatementHasNoEffectChecker.ER_ID, StatementHasNoEffectChecker.PARAM_MACRO_ID);
+ macro.setValue(Boolean.TRUE);
+ checkSampleAbove();
+ }
+
+ //#define FUNC(a) a
+ // main() {
+ // int x;
+ // FUNC(x); // error
+ // }
+ public void testMessageInMacro() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ IMarker m = checkErrorLine(4);
+ assertMessageMatch("'FUNC(x)'", m); //$NON-NLS-1$
+ }
+
+ //#define FUNC(a) a
+ // main() {
+ // int a;
+ // FUNC(a); // no error if macro exp turned off
+ // }
+ public void testInMacroParamOff() throws Exception {
+ IProblemPreference macro = getPreference(StatementHasNoEffectChecker.ER_ID, StatementHasNoEffectChecker.PARAM_MACRO_ID);
+ macro.setValue(Boolean.FALSE);
+ checkSampleAbove();
+ }
+
+ // main() {
+ // int a;
+ // +a; // error here on line 3
+ // }
+ public void testMessage() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ IMarker m = checkErrorLine(3);
+ assertMessageMatch("'\\+a'", m); //$NON-NLS-1$
+ }
+
+ // class S {
+ // int operator*(); // may have side effect
+ // };
+ //
+ // int main() {
+ // S s;
+ // *s;
+ // }
+ public void testOverloadedOperator_bug399146() throws Exception {
+ checkSampleAboveCpp();
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/SuggestedParenthesisCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/SuggestedParenthesisCheckerTest.java
new file mode 100644
index 00000000000..78b8acfd6ea
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/SuggestedParenthesisCheckerTest.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2011 Alena Laskavaia
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alena Laskavaia - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import org.eclipse.cdt.codan.core.param.IProblemPreference;
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisChecker;
+
+/**
+ * Test for {@see SuggestedParenthesisChecker} class
+ */
+public class SuggestedParenthesisCheckerTest extends CheckerTestCase {
+ // main() {
+ // int a=1,b=3;
+ // if (!a<10) b=4; // error here on line 3
+ // }
+ public void test1() throws Exception {
+ IProblemPreference macro = getPreference(SuggestedParenthesisChecker.ER_ID, SuggestedParenthesisChecker.PARAM_NOT);
+ macro.setValue(Boolean.TRUE);
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ }
+
+ // main() {
+ // int a=1,b=3;
+ //
+ // if (b+a && a>b || b-a) b--; // error here on line 4
+ // }
+ public void test2() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(4);
+ }
+
+ // main() {
+ // int a=1,b=3;
+ // if (!(a<10)) b=4; // no error here on line 3
+ // }
+ public void test3() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // main() {
+ // int a=1,b=3;
+ // if (a && !b) b=4; // no error here on line 3
+ // }
+ public void test_lastnot() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // main() {
+ // int a=1,b=3;
+ // if ((!a) && 10) b=4; // no error here on line 3
+ // }
+ public void test_fixed() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // main() {
+ // int a=1,b=3;
+ // if (a && b & a) b=4; // error here on line 3
+ // }
+ public void test_mixedbin() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/SuspiciousSemicolonCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/SuspiciousSemicolonCheckerTest.java
new file mode 100644
index 00000000000..cb1b822a228
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/SuspiciousSemicolonCheckerTest.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 Marc-Andre Laperle and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc-Andre Laperle - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonChecker;
+
+public class SuspiciousSemicolonCheckerTest extends CheckerTestCase {
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems("org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem");
+ }
+
+ // void foo() {
+ // if(0);
+ // }
+ public void testIf1() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(2);
+ }
+
+ // void foo() {
+ // if(0);
+ // {
+ // }
+ // }
+ public void testIf2() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(2);
+ }
+
+ // void foo() {
+ // if(0)
+ // foo();
+ // }
+ public void testIf3() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // void foo() {
+ // if(0)
+ // ;
+ // }
+ public void testIf4() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ }
+
+ // void foo() {
+ // if(0);{
+ // }
+ // }
+ public void testIf5() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(2);
+ }
+
+ // void foo() {
+ // if(0) {};
+ // }
+ public void testIf6() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // void foo() {
+ // if(0
+ // );
+ // }
+ // }
+ public void testIf7() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ }
+
+ // void foo() {
+ // if(0)
+ // ;
+ // else if(0);
+ // }
+ public void testElseIf1() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ checkErrorLine(4);
+ }
+
+ // void foo() {
+ // if(0)
+ // ;
+ // else if(0);
+ // {
+ //
+ // }
+ // }
+ public void testElseIf2() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ checkErrorLine(4);
+ }
+
+ // void foo() {
+ // if(0)
+ // ;
+ // else if(0);{
+ // }
+ // }
+ public void testElseIf3() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ checkErrorLine(4);
+ }
+
+ // void foo() {
+ // if(0)
+ // ;
+ // else if(0){};
+ // }
+ public void testElseIf4() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ }
+
+ // void foo() {
+ // if(0)
+ // ;
+ // else if(0
+ // );
+ // }
+ public void testElseIf5() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(3);
+ checkErrorLine(5);
+ }
+
+ // #define OP
+ // void foo() {
+ // if(0)
+ // OP;
+ // }
+ public void testMacro() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // #define MACRO(cond) if (cond) ;
+ // void foo() {
+ // MACRO(true);
+ // }
+ public void testMacroExpansion() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // main() {
+ // if (false)
+ // ; // only this one is reported
+ // else
+ // ;
+ // }
+ public void testIfElse() throws Exception {
+ setPreferenceValue(SuspiciousSemicolonChecker.ER_ID, SuspiciousSemicolonChecker.PARAM_ALFTER_ELSE, Boolean.TRUE);
+ loadCodeAndRun(getAboveComment());
+ checkErrorLines(3, 5);
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/UnusedSymbolInFileScopeCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/UnusedSymbolInFileScopeCheckerTest.java
new file mode 100644
index 00000000000..87eb9e0998e
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/UnusedSymbolInFileScopeCheckerTest.java
@@ -0,0 +1,344 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Andrew Gvozdev and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andrew Gvozdev - initial API and implementation
+ * Sergey Prigogin (Google)
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.cdt.codan.internal.checkers.UnusedSymbolInFileScopeChecker;
+
+/**
+ * Test for {@see UnusedSymbolInFileScopeChecker} class
+ */
+public class UnusedSymbolInFileScopeCheckerTest extends CheckerTestCase {
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems(
+ UnusedSymbolInFileScopeChecker.ER_UNUSED_VARIABLE_DECLARATION_ID,
+ UnusedSymbolInFileScopeChecker.ER_UNUSED_FUNCTION_DECLARATION_ID,
+ UnusedSymbolInFileScopeChecker.ER_UNUSED_STATIC_FUNCTION_ID);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // extern function declarations
+ ////////////////////////////////////////////////////////////////////////////
+
+ // int test_fun();
+ // extern int test_efun();
+ public void testExternFunction_Declaration_Unused() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(1);
+ checkErrorLine(2);
+ }
+
+ // int test_fun();
+ // void fun() {
+ // test_fun();
+ // }
+ public void testExternFunction_Declaration_Used() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // void test_fun();
+ // void test_fun() {}
+ public void testExternFunction_Declaration_FollowedByDefinition() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // extern function definitions
+ ////////////////////////////////////////////////////////////////////////////
+
+ // void test_fun(void) {}
+ public void testExternFunction_Definition() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Static function declarations
+ ////////////////////////////////////////////////////////////////////////////
+
+ // static void test_fun(void);
+ public void testStaticFunction_Declaration_Unused() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(1);
+ }
+
+ // static void test_fun(void);
+ // static void test_fun(void) {}
+ public void testStaticFunction_Declaration_FollowedByDefinition() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(2);
+ }
+
+ // static void test_fun(void);
+ // void fun() {
+ // test_fun();
+ // }
+ public void testStaticFunction_Declaration_Used() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(1);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Static function definitions
+ ////////////////////////////////////////////////////////////////////////////
+
+ // static void test_fun(void) {}
+ public void testStaticFunction_Definition_Unused() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(1);
+ }
+
+ // static void test_fun(void);
+ // static void test_fun(void) {}
+ public void testStaticFunction_Definition_Unused_WithDeclaration() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(2);
+ }
+
+ // static void test_fun(void) {}
+ // void fun() {
+ // test_fun();
+ // }
+ public void testStaticFunction_Definition_Used() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // void fun() {
+ // test_fun();
+ // }
+ // static int test_fun(void) {}
+ public void testStaticFunction_Definition_UsedBeforeDefinition() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // static int test_fun(void) {}
+ // static int test_fun(int) {}
+ // void fun() {
+ // test_fun(0);
+ // }
+ public void testStaticFunction_Definition_Signature() throws Exception {
+ loadCodeAndRunCpp(getAboveComment());
+ checkErrorLine(1);
+ }
+
+ // static int test_fun(void) {}
+ // void fun() {
+ // int test_fun=0;
+ // }
+ public void testStaticFunction_Definition_SynonymLocalScope() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(1);
+ }
+
+ // static int test_fun(void) {}
+ // void fun(int test_fun) {
+ // }
+ public void testStaticFunction_Definition_SynonymArgs() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(1);
+ }
+
+ // static int (test_fun) ();
+ public void testStaticFunction_Definition_InParentheses() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(1);
+ }
+
+ // static int test_fun(int i) {}
+ // int i = test_fun(X);
+ public void testStaticFunction_Definition_UnknownParameterType() throws Exception {
+ loadCodeAndRunCpp(getAboveComment());
+ checkNoErrors();
+ }
+
+ // static void test_fun(void) {}
+ // void Class::fun() {
+ // test_fun();
+ // }
+ public void testStaticFunction_Definition_InQualifiedFunction() throws Exception {
+ loadCodeAndRunCpp(getAboveComment());
+ checkNoErrors();
+ }
+
+ // static int test_fun(X) {}
+ // int i = test_fun(X);
+ public void testStaticFunction_Definition_UnknownArgumentType() throws Exception {
+ loadCodeAndRunCpp(getAboveComment());
+ checkNoErrors();
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Extern variables declaration
+ ////////////////////////////////////////////////////////////////////////////
+
+ // extern int test_var;
+ public void testExternVariable_Declaration_Unused() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(1);
+ }
+
+ // extern int test_var;
+ // void fun() {
+ // test_var=0;
+ // }
+ public void testExternVariable_Declaration_Used() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // extern int i,
+ // test_var;
+ public void testExternVariable_Declaration_Combined() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(1);
+ checkErrorLine(2);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Extern variables definition
+ ////////////////////////////////////////////////////////////////////////////
+
+ // int test_var;
+ // int test_var2=0;
+ public void testGlobalVariable_Definition() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // extern const int test_var=0; // not quite legal but some compilers allow that
+ public void testExternVariable_Definition1() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // extern const int test_var;
+ // const int test_var = 0;
+ public void testExternVariable_Definition2() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Static variables
+ ////////////////////////////////////////////////////////////////////////////
+
+ // static int test_var;
+ public void testStaticVariable_Unused() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(1);
+ }
+
+ // static int (*test_var)(float, char, char);
+ public void testStaticVariable_Unused_FunctionPointer() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(1);
+ }
+
+ // static int test_var;
+ // int i=test_var;
+ public void testStaticVariable_Used_GlobalScope() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // static int test_var;
+ // void fun() {
+ // int i=test_var;
+ // }
+ public void testStaticVariable_Used_LocalScope() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // static int test_var;
+ // void Class::fun() {
+ // test_var = 0;
+ // }
+ public void testStaticVariable_Used_InQualifiedFunction() throws Exception {
+ loadCodeAndRunCpp(getAboveComment());
+ checkNoErrors();
+ }
+
+ // class Class;
+ // static Class test_var; // constructor is called here
+ public void testStaticVariable_Used_Constructor() throws Exception {
+ loadCodeAndRunCpp(getAboveComment());
+ checkNoErrors();
+ }
+
+ // static X test_var; // avoid possible false positive, binding checker would complain anyway
+ public void testExternVariable_Declaration_IgnoreUnresolved() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // static char* test_var="$Id: UnusedSymbolInFileScopeCheckerTest.java,v 1.2 2011/04/29 11:17:42 agvozdev Exp $";
+ public void testExternVariable_Declaration_CvsIdent() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // static char* test_var="@(#) $Header: /cvsroot/tools/org.eclipse.cdt/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/UnusedSymbolInFileScopeCheckerTest.java,v 1.2 2011/04/29 11:17:42 agvozdev Exp $";
+ public void testExternVariable_Declaration_SccsIdent() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // static char test_var[]("@(#) $Id: UnusedSymbolInFileScopeCheckerTest.java,v 1.2 2011/04/29 11:17:42 agvozdev Exp $");
+ public void testExternVariable_Declaration_CvsIdentInitializer() throws Exception {
+ loadCodeAndRunCpp(getAboveComment());
+ checkNoErrors();
+ }
+
+ // static int v1 __attribute__((unused));
+ // int f1() __attribute__((__unused__));
+ // extern int f2() __attribute__((unused));
+ // static void f3() __attribute__((unused));
+ // static void f4() __attribute__((unused));
+ // static void f4() __attribute__((unused)) {}
+ public void testAttributeUnused() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // extern int* pxCurrentTCB;
+ //
+ // int main() {
+ // asm ("lds r26, pxCurrentTCB\n\t");
+ // }
+ public void testUseInAsm_bug393129() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // static void foo(int) {}
+ // static void foo(float) {}
+ //
+ // template <typename T>
+ // void bar(T t) {
+ // foo(t);
+ // }
+ //
+ // int main() {
+ // bar(0);
+ // }
+ public void testOverloadedStaticFunctionUsedInTemplate_bug358694() throws Exception {
+ loadCodeAndRunCpp(getAboveComment());
+ checkNoErrors();
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/param/BasicProblemPreferenceTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/param/BasicProblemPreferenceTest.java
new file mode 100644
index 00000000000..bd94d48c041
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/param/BasicProblemPreferenceTest.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2009,2010 Alena Laskavaia
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alena Laskavaia - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.param;
+
+import java.io.File;
+
+import org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor.PreferenceType;
+
+import junit.framework.TestCase;
+
+/**
+ * Test for BasicProblemPreference
+ */
+public class BasicProblemPreferenceTest extends TestCase {
+ private static final String TEST_STR = "aaa";
+ BasicProblemPreference pref;
+ String key = "xxx";
+
+ @Override
+ protected void setUp() throws Exception {
+ pref = new BasicProblemPreference(key, "My Value");
+ }
+
+ public void testIntegerExportValue() {
+ pref.setType(PreferenceType.TYPE_INTEGER);
+ pref.setValue(22);
+ String value = pref.exportValue();
+ assertEquals(String.valueOf(22), value);
+ }
+
+ public void testIntegerImportValue() {
+ pref.setType(PreferenceType.TYPE_INTEGER);
+ pref.importValue("22");
+ assertEquals(22, pref.getValue());
+ }
+
+ public void testStringExportValue() {
+ pref.setType(PreferenceType.TYPE_STRING);
+ pref.setValue(TEST_STR);
+ String value = pref.exportValue();
+ assertEquals(TEST_STR, value);
+ }
+
+ public void testStringImportValue() {
+ pref.setType(PreferenceType.TYPE_STRING);
+ pref.importValue(TEST_STR);
+ assertEquals(TEST_STR, pref.getValue());
+ }
+
+ public void testBooleanImportValue() {
+ pref.setType(PreferenceType.TYPE_BOOLEAN);
+ pref.setValue(Boolean.TRUE);
+ String value = pref.exportValue();
+ assertEquals("true", value);
+ pref.importValue(TEST_STR);
+ assertEquals(Boolean.FALSE, pref.getValue());
+ }
+
+ public void testFileImportValue() {
+ pref.setType(PreferenceType.TYPE_FILE);
+ File file = new File("file.c");
+ pref.setValue(file);
+ String value = pref.exportValue();
+ assertEquals(file.getName(), value);
+ pref.importValue(file.getName());
+ assertEquals(file, pref.getValue());
+ }
+
+ public void testBadKey() {
+ try {
+ pref.setKey(null);
+ fail("Should be exception");
+ } catch (Exception e) {
+ assertTrue(true);
+ }
+ }
+
+ public void testBadType() {
+ try {
+ pref.setType(null);
+ fail("Should be exception");
+ } catch (Exception e) {
+ assertTrue(true);
+ }
+ }
+
+ public void testStringImportValueNum() {
+ pref.setType(PreferenceType.TYPE_STRING);
+ pref.importValue("42.5");
+ assertEquals("42.5", pref.getValue());
+ }
+
+ /**
+ * @param str
+ */
+ protected void checkImportExport(String str) {
+ pref.setType(PreferenceType.TYPE_STRING);
+ pref.setValue(str);
+ pref.importValue(pref.exportValue());
+ assertEquals(str, pref.getValue());
+ }
+
+ public void testStringExportSpecial() {
+ checkImportExport("a=b");
+ checkImportExport("\"");
+ checkImportExport("33");
+ checkImportExport("22.4");
+ checkImportExport("a,b");
+ checkImportExport("{a+b}");
+ checkImportExport("\b");
+ }
+ // public void testEscape() {
+ // String str = "\"a\"";
+ // String res = pref.escape(str);
+ // assertEquals("\"\\\"a\\\"\"", res);
+ // }
+ //
+ // public void testUnEscape() {
+ // String res = "\"a\"";
+ // String str = "\"\\\"a\\\"\"";
+ // assertEquals(res, pref.unescape(str));
+ // }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/param/ListProblemPreferenceTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/param/ListProblemPreferenceTest.java
new file mode 100644
index 00000000000..095a643e3a0
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/param/ListProblemPreferenceTest.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2009,2010 Alena Laskavaia
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alena Laskavaia - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.param;
+
+import java.util.Arrays;
+
+import org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor.PreferenceType;
+
+import junit.framework.TestCase;
+
+/**
+ * Test for BasicProblemPreference
+ */
+public class ListProblemPreferenceTest extends TestCase {
+ private static final String PAR1 = "0";
+ private static final String PAR2 = "1";
+ private ListProblemPreference list;
+ private String key = "list";
+ private ListProblemPreference list2;
+
+ @Override
+ protected void setUp() throws Exception {
+ list = new ListProblemPreference(key, "My Value");
+ list2 = new ListProblemPreference(key, "My Value2");
+ }
+
+ /**
+ * @param parval
+ * @return
+ */
+ protected BasicProblemPreference addPar(String key, Object parval) {
+ BasicProblemPreference str = makePar(key, parval);
+ list.addChildDescriptor(str);
+ return (BasicProblemPreference) list.getChildDescriptor(key);
+ }
+
+ /**
+ * @param parval
+ * @param parval
+ * @return
+ */
+ protected BasicProblemPreference makePar(String key, Object parval) {
+ BasicProblemPreference str = new BasicProblemPreference(key, key);
+ if (parval != null) {
+ str.setValue(parval);
+ str.setType(PreferenceType.typeOf(parval));
+ }
+ return str;
+ }
+
+ public void testExportValueStr() {
+ BasicProblemPreference str = addPar(PAR1, "42.5");
+ String value = list.exportValue();
+ assertEquals("(42.5)", value);
+ }
+
+ public void testImportValue() {
+ addPar(PAR1, "xxx");
+ String value = list.exportValue();
+ BasicProblemPreference str2 = new BasicProblemPreference(PAR1, PAR1);
+ list2.addChildDescriptor(str2);
+ list2.importValue(value);
+ assertEquals("xxx", list2.getChildValue(PAR1));
+ }
+
+ public void testImportValueSpec() {
+ BasicProblemPreference str = addPar(PAR1, "a=b");
+ String value = list.exportValue();
+ BasicProblemPreference str2 = new BasicProblemPreference(PAR1, PAR1);
+ list2.addChildDescriptor(str2);
+ list2.importValue(value);
+ assertEquals(str.getValue(), list2.getChildValue(PAR1));
+ }
+
+ public void testImportValue2() {
+ addPar(PAR1, "a=b");
+ BasicProblemPreference p2 = addPar(PAR2, "2,\"2");
+ String value = list.exportValue();
+ list = new ListProblemPreference(key, "My Value");
+ addPar(PAR1, null);
+ addPar(PAR2, null);
+ list.importValue(value);
+ assertEquals("a=b", list.getChildValue(PAR1));
+ assertEquals(p2.getValue(), list.getChildValue(PAR2));
+ }
+
+ public void testImportValue2_nosec() {
+ addPar(PAR1, "a=b");
+ BasicProblemPreference p2 = addPar(PAR2, "2' 2\"");
+ String value = list.exportValue();
+ list = new ListProblemPreference(key, "My Value");
+ addPar(PAR1, null);
+ list.importValue(value);
+ assertEquals("a=b", list.getChildValue(PAR1));
+ assertEquals(p2.getValue(), list.getChildValue(PAR2));
+ }
+
+ public void testGetValue() {
+ list.setChildDescriptor(new BasicProblemPreference("#", "Value"));
+ String x[] = { "a", "b" };
+ list.addChildValue(x[0]);
+ list.addChildValue(x[1]);
+ Object[] values = list.getValues();
+ assertTrue(Arrays.deepEquals(x, values));
+ }
+
+ public void testSetValue() {
+ list.setChildDescriptor(new BasicProblemPreference("#", "Value"));
+ String x[] = { "a", "b" };
+ list.setValue(x);
+ Object[] values = list.getValues();
+ assertTrue(Arrays.deepEquals(x, values));
+ }
+
+ public void testSetValueImport() {
+ list.setChildDescriptor(new BasicProblemPreference("#", "Value"));
+ String x[] = { "a", "b" };
+ list.setValue(x);
+ list.importValue("(x)");
+ Object[] values = list.getValues();
+ assertEquals(1, values.length);
+ assertEquals("x", values[0]);
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/param/MapProblemPreferenceTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/param/MapProblemPreferenceTest.java
new file mode 100644
index 00000000000..e0abcb169c3
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/param/MapProblemPreferenceTest.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2009,2010 Alena Laskavaia
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alena Laskavaia - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.param;
+
+import org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor.PreferenceType;
+
+import junit.framework.TestCase;
+
+/**
+ * Test for BasicProblemPreference
+ */
+public class MapProblemPreferenceTest extends TestCase {
+ private static final String PAR1 = "aaa";
+ private static final String PAR2 = "bbb";
+ private MapProblemPreference map;
+ private String key = "map";
+ private MapProblemPreference map2;
+
+ @Override
+ protected void setUp() throws Exception {
+ map = new MapProblemPreference(key, "My Value");
+ map2 = new MapProblemPreference(key, "My Value2");
+ }
+
+ /**
+ * @param parval
+ * @return
+ */
+ protected BasicProblemPreference addPar(String key, Object parval) {
+ BasicProblemPreference str = makePar(key, parval);
+ map.addChildDescriptor(str);
+ return str;
+ }
+
+ /**
+ * @param parval
+ * @param parval
+ * @return
+ */
+ protected BasicProblemPreference makePar(String key, Object parval) {
+ BasicProblemPreference str = new BasicProblemPreference(key, key);
+ if (parval != null) {
+ str.setValue(parval);
+ str.setType(PreferenceType.typeOf(parval));
+ }
+ return str;
+ }
+
+ public void testExportValueStr() {
+ BasicProblemPreference str = addPar(PAR1, "42.5");
+ String value = map.exportValue();
+ assertEquals("{" + str.getKey() + "=>42.5}", value);
+ }
+
+ public void testImportValue() {
+ addPar(PAR1, "xxx");
+ String value = map.exportValue();
+ BasicProblemPreference str2 = new BasicProblemPreference(PAR1, PAR1);
+ map2.addChildDescriptor(str2);
+ map2.importValue(value);
+ assertEquals("xxx", map2.getChildValue(PAR1));
+ }
+
+ public void testImportValueSpec() {
+ BasicProblemPreference str = addPar(PAR1, "a=b");
+ String value = map.exportValue();
+ BasicProblemPreference str2 = new BasicProblemPreference(PAR1, PAR1);
+ map2.addChildDescriptor(str2);
+ map2.importValue(value);
+ assertEquals(str.getValue(), map2.getChildValue(PAR1));
+ }
+
+ public void testImportValue2() {
+ addPar(PAR1, "a=b");
+ BasicProblemPreference p2 = addPar(PAR2, "2,\"2");
+ String value = map.exportValue();
+ map = new MapProblemPreference(key, "My Value");
+ addPar(PAR1, null);
+ addPar(PAR2, null);
+ map.importValue(value);
+ assertEquals("a=b", map.getChildValue(PAR1));
+ assertEquals(p2.getValue(), map.getChildValue(PAR2));
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/AutomatedIntegrationSuite.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/AutomatedIntegrationSuite.java
new file mode 100644
index 00000000000..79093b226e8
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/AutomatedIntegrationSuite.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2015 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - initial API and implementation
+ * Markus Schorn (Wind River Systems)
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.tests;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.eclipse.cdt.codan.core.internal.checkers.AbstractClassInstantiationCheckerTest;
+import org.eclipse.cdt.codan.core.internal.checkers.AssignmentInConditionCheckerTest;
+import org.eclipse.cdt.codan.core.internal.checkers.AssignmentToItselfCheckerTest;
+import org.eclipse.cdt.codan.core.internal.checkers.CaseBreakCheckerTest;
+import org.eclipse.cdt.codan.core.internal.checkers.CatchByReferenceTest;
+import org.eclipse.cdt.codan.core.internal.checkers.ClassMembersInitializationCheckerTest;
+import org.eclipse.cdt.codan.core.internal.checkers.CommentCheckerLineTests;
+import org.eclipse.cdt.codan.core.internal.checkers.CommentCheckerNestedTests;
+import org.eclipse.cdt.codan.core.internal.checkers.FormatStringCheckerTest;
+import org.eclipse.cdt.codan.core.internal.checkers.NonVirtualDestructorCheckerTest;
+import org.eclipse.cdt.codan.core.internal.checkers.ProblemBindingCheckerTest;
+import org.eclipse.cdt.codan.core.internal.checkers.ReturnCheckerTest;
+import org.eclipse.cdt.codan.core.internal.checkers.ReturnStyleCheckerTest;
+import org.eclipse.cdt.codan.core.internal.checkers.StatementHasNoEffectCheckerTest;
+import org.eclipse.cdt.codan.core.internal.checkers.SuggestedParenthesisCheckerTest;
+import org.eclipse.cdt.codan.core.internal.checkers.SuspiciousSemicolonCheckerTest;
+import org.eclipse.cdt.codan.core.internal.checkers.UnusedSymbolInFileScopeCheckerTest;
+import org.eclipse.cdt.codan.internal.checkers.ui.quickfix.AssignmentInConditionQuickFixTest;
+import org.eclipse.cdt.codan.internal.checkers.ui.quickfix.CaseBreakQuickFixTest;
+import org.eclipse.cdt.codan.internal.checkers.ui.quickfix.CatchByReferenceQuickFixTest;
+import org.eclipse.cdt.codan.internal.checkers.ui.quickfix.CreateLocalVariableQuickFixTest;
+import org.eclipse.cdt.codan.internal.checkers.ui.quickfix.SuggestedParenthesisQuickFixTest;
+
+public class AutomatedIntegrationSuite extends TestSuite {
+ public AutomatedIntegrationSuite() {
+ }
+
+ public AutomatedIntegrationSuite(Class<? extends TestCase> theClass, String name) {
+ super(theClass, name);
+ }
+
+ public AutomatedIntegrationSuite(Class<? extends TestCase> theClass) {
+ super(theClass);
+ }
+
+ public AutomatedIntegrationSuite(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ final AutomatedIntegrationSuite suite = new AutomatedIntegrationSuite();
+ // checkers
+ suite.addTestSuite(AbstractClassInstantiationCheckerTest.class);
+ suite.addTestSuite(AssignmentInConditionCheckerTest.class);
+ suite.addTestSuite(AssignmentToItselfCheckerTest.class);
+ suite.addTestSuite(CaseBreakCheckerTest.class);
+ suite.addTestSuite(CatchByReferenceTest.class);
+ suite.addTestSuite(ClassMembersInitializationCheckerTest.class);
+ suite.addTestSuite(FormatStringCheckerTest.class);
+ suite.addTestSuite(NonVirtualDestructorCheckerTest.class);
+ suite.addTestSuite(ProblemBindingCheckerTest.class);
+ suite.addTestSuite(ReturnCheckerTest.class);
+ suite.addTestSuite(ReturnStyleCheckerTest.class);
+ suite.addTestSuite(StatementHasNoEffectCheckerTest.class);
+ suite.addTestSuite(SuggestedParenthesisCheckerTest.class);
+ suite.addTestSuite(SuspiciousSemicolonCheckerTest.class);
+ suite.addTestSuite(UnusedSymbolInFileScopeCheckerTest.class);
+ suite.addTestSuite(CommentCheckerLineTests.class);
+ suite.addTestSuite(CommentCheckerNestedTests.class);
+ // framework
+ suite.addTest(CodanFastTestSuite.suite());
+ // quick fixes
+ suite.addTestSuite(CreateLocalVariableQuickFixTest.class);
+ suite.addTestSuite(SuggestedParenthesisQuickFixTest.class);
+ suite.addTestSuite(CatchByReferenceQuickFixTest.class);
+ suite.addTestSuite(CaseBreakQuickFixTest.class);
+ suite.addTestSuite(AssignmentInConditionQuickFixTest.class);
+ return suite;
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CheckerTestCase.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CheckerTestCase.java
new file mode 100644
index 00000000000..2c5d488f3a7
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CheckerTestCase.java
@@ -0,0 +1,261 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2016 Alena Laskavaia
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alena Laskavaia - initial API and implementation
+ * Marc-Andre Laperle
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.tests;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.cdt.codan.core.CodanRuntime;
+import org.eclipse.cdt.codan.core.model.CheckerLaunchMode;
+import org.eclipse.cdt.codan.core.model.IProblem;
+import org.eclipse.cdt.codan.core.model.IProblemProfile;
+import org.eclipse.cdt.codan.core.model.IProblemReporter;
+import org.eclipse.cdt.codan.core.param.IProblemPreference;
+import org.eclipse.cdt.codan.core.param.MapProblemPreference;
+import org.eclipse.cdt.codan.core.param.RootProblemPreference;
+import org.eclipse.cdt.codan.internal.core.model.CodanProblem;
+import org.eclipse.cdt.codan.internal.core.model.CodanProblemMarker;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+
+/**
+ * Base class for tests. If you want to use outside of this plugin, you need
+ * to override {@link #getPlugin()} method and maybe {@link #getSourcePrefix()}
+ * method to get source directory for the tests,
+ * default is "src". To make it read comment from java class, you need to
+ * include this source directory (with test java files) into the build bundle.
+ *
+ */
+@SuppressWarnings("nls")
+public class CheckerTestCase extends CodanTestCase {
+ protected IMarker[] markers;
+
+ public IMarker checkErrorLine(int i) {
+ return checkErrorLine(currentFile, i);
+ }
+
+ public void checkErrorLines(Object... args) {
+ for (Object i : args) {
+ checkErrorLine((Integer) i);
+ }
+ assertEquals(args.length, markers.length);
+ }
+
+ public void checkErrorComments() {
+ for (Object i : errLines) {
+ checkErrorLine((Integer) i);
+ }
+ assertEquals("Expected number of errors " + errLines.size(),errLines.size(), markers.length);
+ }
+
+ public IMarker checkErrorLine(int i, String problemId) {
+ return checkErrorLine(currentFile, i, problemId);
+ }
+
+ public IMarker checkErrorLine(File file, int expectedLine) {
+ return checkErrorLine(file, expectedLine, null);
+ }
+
+ /**
+ * @param expectedLine
+ * - line
+ * @return
+ */
+ public IMarker checkErrorLine(File file, int expectedLine, String problemId) {
+ assertTrue(markers != null);
+ assertTrue("No problems found but should", markers.length > 0); //$NON-NLS-1$
+ boolean found = false;
+ Integer line = null;
+ String mfile = null;
+ IMarker m = null;
+ for (int j = 0; j < markers.length; j++) {
+ m = markers[j];
+ line = getLine(m);
+ mfile = m.getResource().getName();
+ if (line.equals(expectedLine) && (problemId == null || problemId.equals(CodanProblemMarker.getProblemId(m)))) {
+ found = true;
+ if (file != null && !file.getName().equals(mfile))
+ found = false;
+ else
+ break;
+ }
+ }
+ assertEquals("Error on line " + expectedLine + " is not found", Integer.valueOf(expectedLine), line);
+ if (file != null)
+ assertEquals(file.getName(), mfile);
+ assertTrue(found);
+ assertNotNull(m);
+ return m;
+ }
+
+ /**
+ * @param line
+ * @param m
+ * @return
+ */
+ public Integer getLine(IMarker m) {
+ Integer line = null;
+ try {
+ line = (Integer) m.getAttribute(IMarker.LINE_NUMBER);
+ if (line == null || line.equals(-1)) {
+ Object pos = m.getAttribute(IMarker.CHAR_START);
+ line = pos2line(((Integer) pos).intValue());
+ }
+ } catch (CoreException e) {
+ fail(e.getMessage());
+ } catch (IOException e) {
+ fail(e.getMessage());
+ }
+ return line;
+ }
+
+ public void checkNoErrors() {
+ if (markers != null && markers.length > 0) {
+ IMarker m = markers[0];
+ fail("Found " + markers.length + " errors but should not. First " +
+ CodanProblemMarker.getProblemId(m) + " at line " + getLine(m));
+ }
+ }
+
+ public void checkNoErrorsOfKind(String problemId) {
+ if (markers != null && markers.length > 0) {
+ List<IMarker> filtered = new ArrayList<IMarker>(markers.length);
+ for (IMarker m : markers) {
+ if (CodanProblemMarker.getProblemId(m).equals(problemId)) {
+ filtered.add(m);
+ }
+ }
+ if (!filtered.isEmpty()) {
+ IMarker m = filtered.get(0);
+ fail("Found " + filtered.size() + " errors but should not. First " +
+ CodanProblemMarker.getProblemId(m) + " at line " + getLine(m));
+ }
+ }
+ }
+
+ public void runOnProject() {
+ try {
+ indexFiles();
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+ runCodan();
+ }
+
+ public void loadCodeAndRun(String code) throws CoreException {
+ loadcode(code);
+ runCodan();
+ }
+
+ public void loadCodeAndRunCpp(String code) throws CoreException {
+ loadcode(code, true);
+ runCodan();
+ }
+
+ protected void runCodan() {
+ CodanRuntime.getInstance().getBuilder().processResource(cproject.getProject(), new NullProgressMonitor());
+ try {
+ markers = cproject.getProject().findMarkers(IProblemReporter.GENERIC_CODE_ANALYSIS_MARKER_TYPE, true, 1);
+ } catch (CoreException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * @param problemId
+ * @param paramId
+ * @return
+ */
+ protected IProblemPreference getPreference(String problemId, String paramId) {
+ IProblemProfile resourceProfile =
+ CodanRuntime.getInstance().getCheckersRegistry().getResourceProfile(cproject.getResource());
+ IProblem problem = resourceProfile.findProblem(problemId);
+ IProblemPreference pref = ((MapProblemPreference) problem.getPreference()).getChildDescriptor(paramId);
+ return pref;
+ }
+
+ protected IProblemPreference setPreferenceValue(String problemId, String paramId, Object value) {
+ IProblemPreference param = getPreference(problemId, paramId);
+ param.setValue(value);
+ return param;
+ }
+
+ /**
+ * @param string
+ * @param m
+ */
+ public void assertMessageMatch(String pattern, IMarker m) {
+ try {
+ String message = (String) m.getAttribute(IMarker.MESSAGE);
+ if (message.matches(pattern)) {
+ fail("Expected " + message + " to match with /" + pattern //$NON-NLS-1$ //$NON-NLS-2$
+ + "/"); //$NON-NLS-1$
+ }
+ } catch (CoreException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ public void assertMessageContains(CharSequence charSequence, IMarker m) {
+ try {
+ String message = (String) m.getAttribute(IMarker.MESSAGE);
+ if (!message.contains(charSequence)) {
+ fail("Expected " + message + " to contain /" + charSequence //$NON-NLS-1$ //$NON-NLS-2$
+ + "/"); //$NON-NLS-1$
+ }
+ } catch (CoreException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Enable given problems and disable the rest
+ * @param ids
+ */
+ protected void enableProblems(String... ids) {
+ IProblemProfile profile = CodanRuntime.getInstance().getCheckersRegistry().getWorkspaceProfile();
+ IProblem[] problems = profile.getProblems();
+ for (int i = 0; i < problems.length; i++) {
+ IProblem p = problems[i];
+ boolean enabled = false;
+ for (int j = 0; j < ids.length; j++) {
+ String pid = ids[j];
+ if (p.getId().equals(pid)) {
+ enabled = true;
+ // Force the launch mode to FULL_BUILD to make sure we can test the problem even
+ // if by default it is not set to run on FULL_BUILD.
+ IProblemPreference preference = p.getPreference();
+ if (preference instanceof RootProblemPreference) {
+ RootProblemPreference rootProblemPreference = (RootProblemPreference) preference;
+ rootProblemPreference.getLaunchModePreference().enableInLaunchModes(CheckerLaunchMode.RUN_ON_FULL_BUILD);
+ }
+ break;
+ }
+ }
+ ((CodanProblem) p).setEnabled(enabled);
+ }
+ CodanRuntime.getInstance().getCheckersRegistry().updateProfile(cproject.getProject(), profile);
+ }
+
+ protected void checkSampleAbove() throws CoreException {
+ loadCodeAndRun(getAboveComment());
+ checkErrorComments();
+ }
+
+ protected void checkSampleAboveCpp() throws CoreException {
+ loadCodeAndRunCpp(getAboveComment());
+ checkErrorComments();
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanCoreTestActivator.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanCoreTestActivator.java
new file mode 100644
index 00000000000..e11f5e2764f
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanCoreTestActivator.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 Alena Laskavaia and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alena Laskavaia - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.tests;
+
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class CodanCoreTestActivator extends Plugin {
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.cdt.codan.core.test"; //$NON-NLS-1$
+ // The shared instance
+ private static CodanCoreTestActivator plugin;
+
+ /**
+ * The constructor
+ */
+ public CodanCoreTestActivator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static CodanCoreTestActivator getDefault() {
+ return plugin;
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanFastCxxAstTestCase.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanFastCxxAstTestCase.java
new file mode 100644
index 00000000000..5ca94aaef4c
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanFastCxxAstTestCase.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Copyright (c) 2009,2013 QNX Software Systems
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems (Alena Laskavaia) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.tests;
+
+import junit.framework.TestCase;
+
+import org.eclipse.cdt.codan.core.CodanRuntime;
+import org.eclipse.cdt.codan.core.model.IChecker;
+import org.eclipse.cdt.codan.core.model.ICheckerInvocationContext;
+import org.eclipse.cdt.codan.core.model.IProblemLocation;
+import org.eclipse.cdt.codan.core.model.IProblemReporter;
+import org.eclipse.cdt.codan.core.model.IRunnableInEditorChecker;
+import org.eclipse.cdt.codan.internal.core.CheckerInvocationContext;
+import org.eclipse.cdt.core.dom.ast.IASTProblem;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.dom.parser.ISourceCodeParser;
+import org.eclipse.cdt.core.dom.parser.c.ANSICParserExtensionConfiguration;
+import org.eclipse.cdt.core.dom.parser.c.GCCParserExtensionConfiguration;
+import org.eclipse.cdt.core.dom.parser.c.ICParserExtensionConfiguration;
+import org.eclipse.cdt.core.dom.parser.cpp.ANSICPPParserExtensionConfiguration;
+import org.eclipse.cdt.core.dom.parser.cpp.GPPParserExtensionConfiguration;
+import org.eclipse.cdt.core.dom.parser.cpp.ICPPParserExtensionConfiguration;
+import org.eclipse.cdt.core.parser.FileContent;
+import org.eclipse.cdt.core.parser.IScanner;
+import org.eclipse.cdt.core.parser.IScannerInfo;
+import org.eclipse.cdt.core.parser.NullLogService;
+import org.eclipse.cdt.core.parser.ParserLanguage;
+import org.eclipse.cdt.core.parser.ParserMode;
+import org.eclipse.cdt.core.parser.ScannerInfo;
+import org.eclipse.cdt.core.parser.tests.ast2.AST2TestBase;
+import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
+import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
+import org.eclipse.cdt.internal.core.dom.parser.c.GNUCSourceParser;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * TODO: add description
+ */
+@SuppressWarnings({ "nls", "restriction" })
+public abstract class CodanFastCxxAstTestCase extends TestCase {
+ protected IASTTranslationUnit tu;
+
+ protected String getAboveComment() {
+ return getContents(1)[0].toString();
+ }
+
+ protected StringBuilder[] getContents(int sections) {
+ try {
+ CodanCoreTestActivator plugin = CodanCoreTestActivator.getDefault();
+ return TestSourceReader.getContentsForTest(plugin == null ? null : plugin.getBundle(), "src", getClass(), getName(), sections);
+ } catch (IOException e) {
+ fail(e.getMessage());
+ return null;
+ }
+ }
+
+ public boolean isCpp() {
+ return false;
+ }
+
+ private static final NullLogService NULL_LOG = new NullLogService();
+
+ /**
+ * @return
+ *
+ */
+ public IASTTranslationUnit parse(String code) {
+ return parse(code, isCpp() ? ParserLanguage.CPP : ParserLanguage.C, true);
+ }
+
+ protected IASTTranslationUnit parse(String code, ParserLanguage lang, boolean gcc) {
+ FileContent codeReader = FileContent.create("code.c", code.toCharArray());
+ IScannerInfo scannerInfo = new ScannerInfo();
+ IScanner scanner = AST2TestBase.createScanner(codeReader, lang, ParserMode.COMPLETE_PARSE, scannerInfo);
+ ISourceCodeParser parser2 = null;
+ if (lang == ParserLanguage.CPP) {
+ ICPPParserExtensionConfiguration config = null;
+ if (gcc)
+ config = new GPPParserExtensionConfiguration();
+ else
+ config = new ANSICPPParserExtensionConfiguration();
+ parser2 = new GNUCPPSourceParser(scanner, ParserMode.COMPLETE_PARSE, NULL_LOG, config);
+ } else {
+ ICParserExtensionConfiguration config = null;
+ if (gcc)
+ config = new GCCParserExtensionConfiguration();
+ else
+ config = new ANSICParserExtensionConfiguration();
+ parser2 = new GNUCSourceParser(scanner, ParserMode.COMPLETE_PARSE, NULL_LOG, config);
+ }
+ IASTTranslationUnit tu = parser2.parse();
+ if (parser2.encounteredError() && !hasCodeErrors())
+ fail("PARSE FAILURE");
+ if (!hasCodeErrors()) {
+ if (lang == ParserLanguage.C) {
+ IASTProblem[] problems = CVisitor.getProblems(tu);
+ assertEquals(problems.length, 0);
+ } else if (lang == ParserLanguage.CPP) {
+ IASTProblem[] problems = CPPVisitor.getProblems(tu);
+ assertEquals(problems.length, 0);
+ }
+ }
+ this.tu = tu;
+ return tu;
+ }
+
+ /**
+ * Override if any of code that test tried to parse has errors, otherwise
+ * parse method would assert
+ *
+ * @return
+ */
+ protected boolean hasCodeErrors() {
+ return false;
+ }
+
+ public class ProblemInstance {
+ String id;
+ IProblemLocation loc;
+ Object[] args;
+
+ /**
+ * @param id
+ * @param loc
+ * @param args
+ */
+ public ProblemInstance(String id, IProblemLocation loc, Object[] args) {
+ this.id = id;
+ this.loc = loc;
+ this.args = args;
+ }
+ }
+ private ArrayList<ProblemInstance> codanproblems = new ArrayList<CodanFastCxxAstTestCase.ProblemInstance>();
+
+ void runCodan(String code) {
+ tu = parse(code);
+ runCodan(tu);
+ }
+
+ void runCodan(IASTTranslationUnit tu) {
+ IProblemReporter problemReporter = CodanRuntime.getInstance().getProblemReporter();
+ CodanRuntime.getInstance().setProblemReporter(new IProblemReporter() {
+ public void reportProblem(String problemId, IProblemLocation loc, Object... args) {
+ codanproblems.add(new ProblemInstance(problemId, loc, args));
+ }
+ });
+ ICheckerInvocationContext context = new CheckerInvocationContext(null);
+ try {
+ IChecker checker = getChecker();
+ ((IRunnableInEditorChecker) checker).processModel(tu, context);
+ } finally {
+ CodanRuntime.getInstance().setProblemReporter(problemReporter);
+ context.dispose();
+ }
+ }
+
+ /**
+ * @return
+ */
+ public abstract IChecker getChecker();
+
+ protected int line2offset(int linePar, String code) throws IOException {
+ byte[] bytes = code.getBytes();
+ int line = 1;
+ for (int j = 0; j < bytes.length; j++) {
+ byte c = bytes[j];
+ if (line >= linePar)
+ return j;
+ if (c == '\n')
+ line++;
+ }
+ return 0;
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanFastTestSuite.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanFastTestSuite.java
new file mode 100644
index 00000000000..e1147e315ea
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanFastTestSuite.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2011 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - initial API and implementation
+ * Markus Schorn (Wind River Systems)
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.tests;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.eclipse.cdt.codan.core.cfg.ControlFlowGraphTest;
+import org.eclipse.cdt.codan.core.cxx.CxxAstUtilsTest;
+import org.eclipse.cdt.codan.core.param.BasicProblemPreferenceTest;
+import org.eclipse.cdt.codan.core.param.ListProblemPreferenceTest;
+import org.eclipse.cdt.codan.core.param.MapProblemPreferenceTest;
+
+public class CodanFastTestSuite extends TestSuite {
+ public CodanFastTestSuite() {
+ }
+
+ public CodanFastTestSuite(Class<? extends TestCase> theClass, String name) {
+ super(theClass, name);
+ }
+
+ public CodanFastTestSuite(Class<? extends TestCase> theClass) {
+ super(theClass);
+ }
+
+ public CodanFastTestSuite(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ final CodanFastTestSuite suite = new CodanFastTestSuite();
+ suite.addTestSuite(BasicProblemPreferenceTest.class);
+ suite.addTestSuite(ListProblemPreferenceTest.class);
+ suite.addTestSuite(MapProblemPreferenceTest.class);
+ suite.addTestSuite(CxxAstUtilsTest.class);
+ suite.addTestSuite(ControlFlowGraphTest.class);
+ return suite;
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanTestCase.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanTestCase.java
new file mode 100644
index 00000000000..718a998799a
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/CodanTestCase.java
@@ -0,0 +1,274 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2015 Alena Laskavaia
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alena Laskavaia - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.tests;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.regex.Pattern;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.IPDOMManager;
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.testplugin.CProjectHelper;
+import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
+import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Plugin;
+
+/**
+ * TODO: add description
+ */
+@SuppressWarnings("nls")
+public class CodanTestCase extends BaseTestCase {
+ ArrayList<File> tempFiles = new ArrayList<File>();
+ protected File tmpDir;
+ protected ICProject cproject;
+ protected File currentFile;
+ protected ICElement currentCElem;
+ protected IFile currentIFile;
+ protected ArrayList<Integer> errLines = new ArrayList<Integer>();
+
+ /**
+ *
+ */
+ public CodanTestCase() {
+ super();
+ }
+
+ /**
+ * @param name
+ */
+ public CodanTestCase(String name) {
+ super(name);
+ }
+
+ /**
+ * Override for c++ (i.e. at least one c++ test)
+ *
+ * @return is c++ tests
+ */
+ public boolean isCpp() {
+ return false;
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ removeLeftOverProjects();
+ cproject = createProject(isCpp());
+ tmpDir = cproject.getProject().getLocation().makeAbsolute().toFile();
+ // this make CodanRunner to propagate all exceptions it normally just logs
+ System.setProperty("codan.rethrow", "true"); // test can override setUp and unset this
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ if (cproject != null) {
+ try {
+ cproject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor());
+ } catch (CoreException e) {
+ throw e;
+ }
+ }
+ super.tearDown();
+ }
+
+ /**
+ * @throws CoreException
+ */
+ private void removeLeftOverProjects() throws CoreException {
+ try {
+ final IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IProject[] projects = workspace.getRoot().getProjects();
+ for (int i = 0; i < projects.length; i++) {
+ IProject p = projects[i];
+ if (p.getName().startsWith("Codan")) {
+ p.delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor());
+ }
+ }
+ } catch (Throwable e) {
+ // moving on...
+ }
+ }
+
+ protected ICProject createProject(final boolean cpp) throws CoreException {
+ final ICProject cprojects[] = new ICProject[1];
+ ModelJoiner mj = new ModelJoiner();
+ try {
+ // Create the cproject
+ final String projectName = "CodanProjTest_" + System.currentTimeMillis();
+ final IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ workspace.run(new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ // Create the cproject
+ ICProject cproject = cpp ? CProjectHelper.createCCProject(projectName, null, IPDOMManager.ID_NO_INDEXER)
+ : CProjectHelper.createCProject(projectName, null, IPDOMManager.ID_NO_INDEXER);
+ cprojects[0] = cproject;
+ }
+ }, null);
+ mj.join();
+ } finally {
+ mj.dispose();
+ }
+ return cprojects[0];
+ }
+
+ protected void indexFiles() throws CoreException, InterruptedException {
+ final IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ workspace.run(new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ cproject.getProject().refreshLocal(1, monitor);
+ }
+ }, null);
+ // Index the cproject
+ CCorePlugin.getIndexManager().setIndexerId(cproject, IPDOMManager.ID_FAST_INDEXER);
+ CCorePlugin.getIndexManager().reindex(cproject);
+ // wait until the indexer is done
+ waitForIndexer(cproject);
+ }
+
+ /**
+ * @param pos
+ * @return
+ * @throws IOException
+ */
+ protected int pos2line(int pos) throws IOException {
+ FileInputStream st = new FileInputStream(currentFile);
+ try {
+ int c;
+ int line = 1;
+ int cur = 0;
+ while ((c = st.read()) != -1) {
+ if (c == '\n')
+ line++;
+ if (cur >= pos)
+ return line;
+ cur++;
+ }
+ } finally {
+ st.close();
+ }
+ return 0;
+ }
+
+ protected String getAboveComment() {
+ return getContents(1)[0].toString();
+ }
+
+ protected StringBuilder[] getContents(int sections) {
+ try {
+ return TestSourceReader.getContentsForTest(getPlugin().getBundle(), getSourcePrefix(), getClass(), getName(), sections);
+ } catch (IOException e) {
+ fail(e.getMessage());
+ return null;
+ }
+ }
+
+ protected String getSourcePrefix() {
+ return "src";
+ }
+
+ protected Plugin getPlugin() {
+ CodanCoreTestActivator plugin = CodanCoreTestActivator.getDefault();
+ return plugin;
+ }
+
+ public File loadcode(String code, boolean cpp) throws CoreException {
+ String fileKey = "@file:";
+ int indf = code.indexOf(fileKey);
+ if (indf >= 0) {
+ int sep = code.indexOf('\n');
+ if (sep != -1) {
+ String line = code.substring(0, sep);
+ code = code.substring(sep + 1);
+ String fileName = line.substring(indf + fileKey.length()).trim();
+ return loadcode(code, new File(tmpDir, fileName));
+ }
+ }
+ String ext = cpp ? ".cpp" : ".c";
+ File testFile = null;
+ try {
+ testFile = File.createTempFile("test", ext, tmpDir); //$NON-NLS-1$
+ } catch (IOException e1) {
+ fail(e1.getMessage());
+ return null;
+ }
+ return loadcode(code, testFile);
+ }
+
+ private File loadcode(String code, File testFile) throws CoreException {
+ try {
+ tempFiles.add(testFile);
+ loadErrorComments(code);
+ TestUtils.saveFile(new ByteArrayInputStream(code.getBytes()), testFile);
+ currentFile = testFile;
+ try {
+ cproject.getProject().refreshLocal(1, null);
+ waitForIndexer(cproject);
+ } catch (InterruptedException e) {
+ }
+ currentCElem = cproject.findElement(new Path(currentFile.toString()));
+ currentIFile = (IFile) currentCElem.getResource();
+ return testFile;
+ } catch (IOException e) {
+ fail("Cannot save test: " + testFile + ": " + e.getMessage());
+ return null;
+ } catch (CModelException e) {
+ fail("Cannot find file: " + testFile + ": " + e.getMessage());
+ return null;
+ }
+ }
+ private static Pattern COMMENT_TAG_PATTERN = Pattern.compile("//\\s*(err|ERR|ERROR|error)\\b");
+
+ private void loadErrorComments(String trim) {
+ String[] lines = trim.split("\n");
+ for (int i = 0; i < lines.length; i++) {
+ String string = lines[i];
+ if (COMMENT_TAG_PATTERN.matcher(string).find()) {
+ errLines.add(i + 1);
+ }
+ }
+ }
+
+ public File loadcode_c(String code) throws CoreException {
+ return loadcode(code, true);
+ }
+
+ public File loadcode_cpp(String code) throws CoreException {
+ return loadcode(code, false);
+ }
+
+ public File loadcode(String code) throws CoreException {
+ return loadcode(code, isCpp());
+ }
+
+ public File loadcode(CharSequence... more) throws CoreException {
+ File file = null;
+ for (CharSequence cseq : more) {
+ file = loadcode(cseq.toString(), isCpp());
+ }
+ return file;
+ }
+} \ No newline at end of file
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/TestUtils.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/TestUtils.java
new file mode 100644
index 00000000000..471fcbae883
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/TestUtils.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2015 Alena Laskavaia
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alena Laskavaia - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.tests;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.net.URL;
+
+/**
+ * TODO: add description
+ */
+@SuppressWarnings("nls")
+public class TestUtils {
+ public static File saveFile(InputStream st, File testFile) throws FileNotFoundException, IOException {
+ BufferedReader r = new BufferedReader(new InputStreamReader(st));
+ String line;
+ PrintStream wr = new PrintStream(testFile);
+ try {
+ while ((line = r.readLine()) != null) {
+ wr.println(line);
+ }
+ } finally {
+ wr.close();
+ }
+ return testFile;
+ }
+
+ public static String loadFile(InputStream st) throws IOException {
+ BufferedReader br = new BufferedReader(new InputStreamReader(st));
+ String buffer;
+ StringBuilder result = new StringBuilder();
+ while ((buffer = br.readLine()) != null) {
+ result.append(buffer);
+ }
+ st.close();
+ return result.toString();
+ }
+
+ /**
+ * @param clazz
+ * @return
+ * @throws IOException
+ */
+ public static InputStream getJavaFileText(String srcRoot, Class<?> clazz) throws IOException {
+ CodanCoreTestActivator plugin = CodanCoreTestActivator.getDefault();
+ String classFile = clazz.getName().replaceAll("\\.", "/");
+ classFile += ".java";
+ InputStream st = null;
+ if (plugin != null) {
+ URL resource = plugin.getBundle().getResource(srcRoot + "/" + classFile);
+ if (resource == null)
+ throw new IOException("Cannot find file " + srcRoot + "/" + classFile + " in bundle " + plugin.getBundle().getBundleId());
+ st = resource.openStream();
+ } else {
+ st = clazz.getResourceAsStream("/" + classFile);
+ }
+ return st;
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/AssignmentInConditionQuickFixTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/AssignmentInConditionQuickFixTest.java
new file mode 100644
index 00000000000..092764fdf8f
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/AssignmentInConditionQuickFixTest.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Nathan Ridge
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Nathan Ridge - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.internal.checkers.ui.quickfix;
+
+import org.eclipse.cdt.codan.ui.AbstractCodanCMarkerResolution;
+
+public class AssignmentInConditionQuickFixTest extends QuickFixTestCase {
+ @SuppressWarnings("restriction")
+ @Override
+ protected AbstractCodanCMarkerResolution createQuickFix() {
+ return new QuickFixAssignmentInCondition();
+ }
+
+ // void func() {
+ // int a, b;
+ // if (a == 1 && b = 2) {
+ // }
+ // }
+ public void testComparisonAndAssignment_bug352267() throws Exception {
+ loadcode(getAboveComment());
+ String result = runQuickFixOneFile();
+ assertContainedIn("b == 2", result);
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/CaseBreakQuickFixTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/CaseBreakQuickFixTest.java
new file mode 100644
index 00000000000..bafe92bc2ae
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/CaseBreakQuickFixTest.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Tomasz Wesolowski and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tomasz Wesolowski - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.internal.checkers.ui.quickfix;
+
+import org.eclipse.cdt.codan.ui.AbstractCodanCMarkerResolution;
+
+public class CaseBreakQuickFixTest extends QuickFixTestCase {
+ @SuppressWarnings("restriction")
+ @Override
+ protected AbstractCodanCMarkerResolution createQuickFix() {
+ return new CaseBreakQuickFixBreak();
+ }
+
+ //void func() {
+ // int a;
+ // switch(a) {
+ // case 1:
+ // hello();
+ // case 2:
+ // break;
+ // }
+ //}
+ public void testSimpleCase() throws Exception {
+ loadcode(getAboveComment());
+ String result = runQuickFixOneFile();
+ assertContainedIn("break;\tcase 2:", result);
+ }
+
+ //void func() {
+ // int a;
+ // switch(a) {
+ // case 1: {
+ // hello();
+ // }
+ // default:
+ // }
+ //}
+ public void testCompositeStatementCase() throws Exception {
+ loadcode(getAboveComment());
+ String result = runQuickFixOneFile();
+ assertContainedIn("hello();\t\tbreak;", result);
+ }
+
+ // int main() {
+ // int a;
+ // switch(a)
+ // {
+ // case 0:
+ // {
+ // }
+ // default:
+ // break;
+ // }
+ // return 0;
+ // }
+ public void testNPE_bug363884() throws Exception {
+ loadcode(getAboveComment());
+ String result = runQuickFixOneFile();
+ assertContainedIn("break;\t}\t\t\tdefault:", result);
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/CatchByReferenceQuickFixTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/CatchByReferenceQuickFixTest.java
new file mode 100644
index 00000000000..d3dd2f85391
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/CatchByReferenceQuickFixTest.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 Tomasz Wesolowski and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tomasz Wesolowski - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.internal.checkers.ui.quickfix;
+
+import org.eclipse.cdt.codan.internal.checkers.CatchByReference;
+import org.eclipse.cdt.codan.ui.AbstractCodanCMarkerResolution;
+
+/**
+ * @author Tomasz Wesolowski
+ */
+@SuppressWarnings("restriction")
+public class CatchByReferenceQuickFixTest extends QuickFixTestCase {
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems(CatchByReference.ER_ID);
+ }
+
+ @Override
+ public boolean isCpp() {
+ return true;
+ }
+
+ @Override
+ protected AbstractCodanCMarkerResolution createQuickFix() {
+ return null; // quick fix to be chosen per test
+ }
+
+ // struct C {
+ // };
+ // void foo() {
+ // try {
+ // } catch (C exception) {
+ // }
+ // }
+ public void testCatchByReference() throws Exception {
+ setQuickFix(new CatchByReferenceQuickFix());
+ loadcode(getAboveComment());
+ String result = runQuickFixOneFile();
+ assertContainedIn("catch (C & exception)", result); //$NON-NLS-1$
+ }
+
+ // struct C {
+ // };
+ // void foo() {
+ // try {
+ // } catch (C) {
+ // }
+ // }
+ public void testCatchByReferenceNoDeclName() throws Exception {
+ setQuickFix(new CatchByReferenceQuickFix());
+ loadcode(getAboveComment());
+ String result = runQuickFixOneFile();
+ assertContainedIn("catch (C &)", result); //$NON-NLS-1$
+ }
+
+ // struct C {
+ // };
+ // void foo() {
+ // try {
+ // } catch (C exception) {
+ // }
+ // }
+ public void testCatchByConstReference() throws Exception {
+ setQuickFix(new CatchByConstReferenceQuickFix());
+ loadcode(getAboveComment());
+ String result = runQuickFixOneFile();
+ assertContainedIn("catch (const C & exception)", result); //$NON-NLS-1$
+ }
+
+ // struct C {
+ // };
+ // void foo() {
+ // try {
+ // } catch (C) {
+ // }
+ // }
+ public void testCatchByConstReferenceNoDeclName() throws Exception {
+ setQuickFix(new CatchByConstReferenceQuickFix());
+ loadcode(getAboveComment());
+ String result = runQuickFixOneFile();
+ assertContainedIn("catch (const C &)", result); //$NON-NLS-1$
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/CreateLocalVariableQuickFixTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/CreateLocalVariableQuickFixTest.java
new file mode 100644
index 00000000000..f721c7ade19
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/CreateLocalVariableQuickFixTest.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 Tomasz Wesolowski and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tomasz Wesolowski - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.internal.checkers.ui.quickfix;
+
+import org.eclipse.cdt.codan.internal.checkers.ProblemBindingChecker;
+import org.eclipse.cdt.codan.ui.AbstractCodanCMarkerResolution;
+
+/**
+ * @author Tomasz Wesolowski
+ */
+public class CreateLocalVariableQuickFixTest extends QuickFixTestCase {
+ @SuppressWarnings("restriction")
+ @Override
+ protected AbstractCodanCMarkerResolution createQuickFix() {
+ return new QuickFixCreateLocalVariable();
+ }
+
+ @Override
+ public boolean isCpp() {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.cdt.codan.core.test.CodanTestCase#setUp()
+ */
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems(ProblemBindingChecker.ERR_ID_FieldResolutionProblem, ProblemBindingChecker.ERR_ID_MethodResolutionProblem,
+ ProblemBindingChecker.ERR_ID_VariableResolutionProblem);
+ }
+
+ // void func() {
+ // aChar = 'a';
+ // }
+ public void testChar() throws Exception {
+ loadcode(getAboveComment());
+ String result = runQuickFixOneFile();
+ assertContainedIn("char aChar;", result); //$NON-NLS-1$
+ }
+
+ // void func() {
+ // aDouble = 40.;
+ // }
+ public void testDouble() throws Exception {
+ loadcode(getAboveComment());
+ String result = runQuickFixOneFile();
+ assertContainedIn("double aDouble;", result); //$NON-NLS-1$
+ }
+
+ // void func() {
+ // aString = "foo";
+ // }
+ public void testString() throws Exception {
+ loadcode(getAboveComment());
+ String result = runQuickFixOneFile();
+ assertContainedIn("const char* aString;", result); //$NON-NLS-1$
+ }
+
+ // void func() {
+ // aWString = L"foo";
+ // }
+ public void testWString() throws Exception {
+ loadcode(getAboveComment());
+ String result = runQuickFixOneFile();
+ assertContainedIn("const wchar_t* aWString;", result); //$NON-NLS-1$
+ }
+
+ // void func() {
+ // aFuncPtr = func;
+ // }
+ public void testFuncPtr() throws Exception {
+ loadcode(getAboveComment());
+ String result = runQuickFixOneFile();
+ assertContainedIn("void (*aFuncPtr)();", result); //$NON-NLS-1$
+ }
+
+ //class Foo {
+ // void bar(char);
+ //};
+ //void func() {
+ //Foo foo;
+ //foo.bar(aChar);
+ //}
+ public void testInMethodCall() throws Exception {
+ loadcode(getAboveComment());
+ indexFiles();
+ String result = runQuickFixOneFile();
+ assertContainedIn("char aChar", result); //$NON-NLS-1$
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/QuickFixTestCase.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/QuickFixTestCase.java
new file mode 100644
index 00000000000..2fd7fa29df2
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/QuickFixTestCase.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2015 QNX Software Systems
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems (Alena Laskavaia) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.internal.checkers.ui.quickfix;
+
+import java.io.IOException;
+
+import org.eclipse.cdt.codan.core.PreferenceConstants;
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.cdt.codan.core.tests.TestUtils;
+import org.eclipse.cdt.codan.internal.ui.CodanUIActivator;
+import org.eclipse.cdt.codan.ui.AbstractCodanCMarkerResolution;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Abstract base class for Quck Fix tests.
+ */
+@SuppressWarnings("restriction")
+public abstract class QuickFixTestCase extends CheckerTestCase {
+ AbstractCodanCMarkerResolution quickFix;
+ Display display;
+
+ /**
+ * Dispatch ui events for at least msec - milliseconds
+ *
+ * @param msec -
+ * milliseconds delay
+ * @param display -
+ * display that dispatches events
+ */
+ public void dispatch(int msec) {
+ long cur = System.currentTimeMillis();
+ long pass = 0;
+ while (pass < msec) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ pass = System.currentTimeMillis() - cur;
+ }
+ }
+
+ public static void closeWelcome() {
+ try {
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ IWorkbenchPage activePage = window.getActivePage();
+ IWorkbenchPart activePart = activePage.getActivePart();
+ if (activePart.getTitle().equals("Welcome")) { //$NON-NLS-1$
+ //activePage.close();
+ activePart.dispose();
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ quickFix = createQuickFix();
+ display = PlatformUI.getWorkbench().getDisplay();
+ closeWelcome();
+ IPreferenceStore store = CodanUIActivator.getDefault().getPreferenceStore(cproject.getProject());
+ // turn off editor reconciler
+ store.setValue(PreferenceConstants.P_RUN_IN_EDITOR, false);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ Display.getDefault().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ IWorkbenchPage[] pages = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPages();
+ for (IWorkbenchPage page : pages) {
+ page.closeAllEditors(false);
+ dispatch(0);
+ }
+ }
+ });
+
+ super.tearDown();
+ }
+
+ /**
+ * @return
+ */
+ protected abstract AbstractCodanCMarkerResolution createQuickFix();
+
+ /**
+ * @param code
+ * @param string
+ * @return
+ */
+ protected ISelection textSelection(String code, String string) {
+ return new TextSelection(code.indexOf(string), string.length());
+ }
+
+ public String runQuickFixOneFile() throws IOException, CoreException {
+ // need to load before running codan because otherwise marker is lost when doing quick fix 8[]
+ runCodan();
+ doRunQuickFix();
+ String result = TestUtils.loadFile(currentIFile.getContents());
+ return result;
+ }
+
+ public void doRunQuickFix() {
+ Display.getDefault().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ for (int i = 0; i < markers.length; i++) {
+ IMarker marker = markers[i];
+ quickFix.run(marker);
+ dispatch(0);
+ }
+ PlatformUI.getWorkbench().saveAllEditors(false);
+ }
+ });
+
+ }
+
+ /**
+ * @param result
+ * @param expected
+ */
+ public void assertContainedIn(String expected, String result) {
+ assertTrue("Text <" + expected + "> not found in <" + result + ">", result.contains(expected)); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ /**
+ * Changes the quick fix to be used
+ * @param quickFix
+ */
+ public void setQuickFix(AbstractCodanCMarkerResolution quickFix) {
+ this.quickFix = quickFix;
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/SuggestedParenthesisQuickFixTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/SuggestedParenthesisQuickFixTest.java
new file mode 100644
index 00000000000..09b0c15b1ce
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/SuggestedParenthesisQuickFixTest.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2009,2012 QNX Software Systems
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems (Alena Laskavaia) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.internal.checkers.ui.quickfix;
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import org.eclipse.cdt.codan.core.tests.TestUtils;
+import org.eclipse.cdt.codan.ui.AbstractCodanCMarkerResolution;
+import org.eclipse.cdt.internal.ui.util.EditorUtility;
+
+/**
+ * Test for quick fix for suggested parenthesis
+ */
+@SuppressWarnings("restriction")
+public class SuggestedParenthesisQuickFixTest extends QuickFixTestCase {
+ @Override
+ public AbstractCodanCMarkerResolution createQuickFix() {
+ return new SuggestedParenthesisQuickFix();
+ }
+
+ // main() {
+ // int a=1,b=3;
+ // if (b+a && a>b || b-a) b--; // error here
+ // }
+ public void testSimple() throws Exception {
+ loadcode(getAboveComment());
+ String result = runQuickFixOneFile();
+ assertContainedIn("(b+a && a>b)", result); //$NON-NLS-1$
+ }
+
+ // @file:header.h
+ // int foo();
+
+ // @file:main.c
+ // #include "header.h"
+ // main() {
+ // foo();
+ // }
+ public void test2FilesExample() throws Exception {
+ /*
+ * There are no problems in either of the two files, so quick fix is not called.
+ */
+ CharSequence[] code = getContents(2);
+ File f1 = loadcode(code[0].toString());
+ File f2 = loadcode(code[1].toString());
+ // lets pretend marker is found in main.c but fixes go in both files,
+ // to check do something like this
+ EditorUtility.openInEditor(f2);
+ runCodan();
+ doRunQuickFix();
+ String result_main = TestUtils.loadFile(new FileInputStream(f2));
+ String result_header = TestUtils.loadFile(new FileInputStream(f1));
+ assertContainedIn("foo", result_main); //$NON-NLS-1$
+ assertContainedIn("foo", result_header); //$NON-NLS-1$
+ }
+}

Back to the top