mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-09 09:15:38 +02:00
[281187] checker was doing the opposite - implemented properly
This commit is contained in:
parent
5e8566888d
commit
47c9b5205a
2 changed files with 37 additions and 13 deletions
|
@ -50,8 +50,10 @@
|
||||||
<problem
|
<problem
|
||||||
category="org.eclipse.cdt.codan.core.categories.ProgrammingProblems"
|
category="org.eclipse.cdt.codan.core.categories.ProgrammingProblems"
|
||||||
defaultSeverity="Warning"
|
defaultSeverity="Warning"
|
||||||
|
description="Catching by reference is recommended by C++ experts, "Throw by value, catch by reference". 
 For one thing, this avoids copying and potentially slicing the exception."
|
||||||
id="org.eclipse.cdt.codan.internal.checkers.CatchUsesReference"
|
id="org.eclipse.cdt.codan.internal.checkers.CatchUsesReference"
|
||||||
name="Catch uses reference to exception">
|
name="Catching by reference is recommended"
|
||||||
|
messagePattern="Catching by reference is recommended for non-basic types">
|
||||||
</problem>
|
</problem>
|
||||||
</checker>
|
</checker>
|
||||||
<checker
|
<checker
|
||||||
|
|
|
@ -13,18 +13,25 @@ package org.eclipse.cdt.codan.internal.checkers;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
|
import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
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.IASTDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTryBlockStatement;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTryBlockStatement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Alena
|
* Catching by reference is recommended by C++ experts, for example Herb Sutter/Andrei Alexandresscu "C++ Coding Standards", Rule 73 "Throw by value, catch by reference".
|
||||||
|
* For one thing, this avoids copying and potentially slicing the exception.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CatchUsesReference extends AbstractIndexAstChecker {
|
public class CatchUsesReference extends AbstractIndexAstChecker {
|
||||||
|
@ -39,14 +46,31 @@ public class CatchUsesReference extends AbstractIndexAstChecker {
|
||||||
OnCatch() {
|
OnCatch() {
|
||||||
shouldVisitStatements = true;
|
shouldVisitStatements = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int visit(IASTStatement stmt) {
|
public int visit(IASTStatement stmt) {
|
||||||
if (stmt instanceof ICPPASTTryBlockStatement) {
|
if (stmt instanceof ICPPASTTryBlockStatement) {
|
||||||
ICPPASTTryBlockStatement tblock = (ICPPASTTryBlockStatement) stmt;
|
ICPPASTTryBlockStatement tblock = (ICPPASTTryBlockStatement) stmt;
|
||||||
ICPPASTCatchHandler[] catchHandlers = tblock.getCatchHandlers();
|
ICPPASTCatchHandler[] catchHandlers = tblock.getCatchHandlers();
|
||||||
for (int i = 0; i < catchHandlers.length; i++) {
|
next: for (int i = 0; i < catchHandlers.length; i++) {
|
||||||
ICPPASTCatchHandler catchHandler = catchHandlers[i];
|
ICPPASTCatchHandler catchHandler = catchHandlers[i];
|
||||||
if (usesReference(catchHandler)) {
|
IASTDeclaration decl = catchHandler.getDeclaration();
|
||||||
reportProblem(ER_ID, catchHandler.getDeclaration(), "Catch clause uses reference in declaration of exception");
|
if (decl instanceof IASTSimpleDeclaration) {
|
||||||
|
IASTSimpleDeclaration sdecl = (IASTSimpleDeclaration) decl;
|
||||||
|
IASTDeclSpecifier spec = sdecl.getDeclSpecifier();
|
||||||
|
if (!usesReference(catchHandler)) {
|
||||||
|
if (spec instanceof ICPPASTNamedTypeSpecifier) {
|
||||||
|
IBinding typeName = ((ICPPASTNamedTypeSpecifier) spec).getName().getBinding();
|
||||||
|
// unwind typedef chain
|
||||||
|
while (typeName instanceof ITypedef) {
|
||||||
|
IType t = ((ITypedef) typeName).getType();
|
||||||
|
if (t instanceof IBasicType) continue next;
|
||||||
|
if (t instanceof IBinding) typeName = (IBinding) t;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
reportProblem(ER_ID, decl);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +78,7 @@ public class CatchUsesReference extends AbstractIndexAstChecker {
|
||||||
}
|
}
|
||||||
return PROCESS_CONTINUE;
|
return PROCESS_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param catchHandler
|
* @param catchHandler
|
||||||
* @return
|
* @return
|
||||||
|
@ -67,9 +92,7 @@ public class CatchUsesReference extends AbstractIndexAstChecker {
|
||||||
IASTPointerOperator[] pointerOperators = d.getPointerOperators();
|
IASTPointerOperator[] pointerOperators = d.getPointerOperators();
|
||||||
for (int j = 0; j < pointerOperators.length; j++) {
|
for (int j = 0; j < pointerOperators.length; j++) {
|
||||||
IASTPointerOperator po = pointerOperators[j];
|
IASTPointerOperator po = pointerOperators[j];
|
||||||
if (po instanceof ICPPASTReferenceOperator) {
|
if (po instanceof ICPPASTReferenceOperator) { return true; }
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,5 +101,4 @@ public class CatchUsesReference extends AbstractIndexAstChecker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue