mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-21 21:52:10 +02:00
Bug 534420 - Added check for nodiscard for classes and enums
Change-Id: I3932f4d23f18f96f8d1c15c18d7d4d991154aca1
This commit is contained in:
parent
77790012cc
commit
dd88f8ffca
2 changed files with 92 additions and 6 deletions
|
@ -28,14 +28,20 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionCall;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||
|
||||
public class NoDiscardChecker extends AbstractAstFunctionChecker {
|
||||
public static final String ER_ID = "org.eclipse.cdt.codan.internal.checkers.NoDiscardProblem"; //$NON-NLS-1$
|
||||
|
@ -101,12 +107,17 @@ public class NoDiscardChecker extends AbstractAstFunctionChecker {
|
|||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
IBinding binding = name.resolveBinding();
|
||||
|
||||
if (binding instanceof IFunction && ((IFunction) binding).isNoDiscard()) {
|
||||
if (expr instanceof ICPPASTExpression) {
|
||||
if (checkEvaluation((ICPPASTExpression) expr)) {
|
||||
return Optional.of(name);
|
||||
} else if ((binding instanceof ICPPClassType || binding instanceof ICPPVariable)
|
||||
&& expr instanceof ICPPASTExpression && checkEvaluation((ICPPASTExpression) expr)) {
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
// For C, the only thing we need to check is IFunction
|
||||
IBinding binding = name.resolveBinding();
|
||||
if (binding instanceof IFunction && ((IFunction) binding).isNoDiscard()) {
|
||||
return Optional.of(name);
|
||||
}
|
||||
|
||||
|
@ -138,8 +149,24 @@ public class NoDiscardChecker extends AbstractAstFunctionChecker {
|
|||
}
|
||||
} else if (eval instanceof EvalFunctionCall) {
|
||||
ICPPFunction evalFunc = ((EvalFunctionCall) eval).resolveFunctionBinding();
|
||||
if (evalFunc != null && evalFunc.isNoDiscard()) {
|
||||
if (evalFunc == null)
|
||||
return false;
|
||||
if (evalFunc.isNoDiscard()) {
|
||||
return true;
|
||||
} else {
|
||||
ICPPFunctionType fType = evalFunc.getType();
|
||||
IType retType = SemanticUtil.getNestedType(fType.getReturnType(), SemanticUtil.TDEF);
|
||||
if (CPPTemplates.isDependentType(retType)) {
|
||||
return false;
|
||||
}
|
||||
if (retType instanceof ICPPReferenceType || retType instanceof IPointerType)
|
||||
return false;
|
||||
retType = SemanticUtil.getUltimateType(retType, true);
|
||||
if (retType instanceof ICPPClassType) {
|
||||
return ((ICPPClassType) retType).isNoDiscard();
|
||||
} else if (retType instanceof ICPPEnumeration) {
|
||||
return ((ICPPEnumeration) retType).isNoDiscard();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -12,6 +12,7 @@ package org.eclipse.cdt.codan.core.internal.checkers;
|
|||
|
||||
import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
|
||||
import org.eclipse.cdt.codan.internal.checkers.NoDiscardChecker;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
|
||||
|
||||
/**
|
||||
* Test for {@link NoDiscardChecker} class
|
||||
|
@ -384,4 +385,62 @@ public class NoDiscardCheckerTest extends CheckerTestCase {
|
|||
loadCodeAndRun(getAboveComment());
|
||||
checkErrorLine(6, ER_ID);
|
||||
}
|
||||
|
||||
//struct [[nodiscard]] error_info { };
|
||||
//error_info enable_missile_safety_mode();
|
||||
//void launch_missiles();
|
||||
//void test_missiles() {
|
||||
// enable_missile_safety_mode();
|
||||
// launch_missiles();
|
||||
//}
|
||||
public void testClassNoDiscardType() throws Exception {
|
||||
loadCodeAndRun(getAboveComment());
|
||||
checkErrorLine(5, ER_ID);
|
||||
}
|
||||
|
||||
//struct [[nodiscard]] error_type {};
|
||||
//error_info& foo();
|
||||
//void f1() {
|
||||
// foo();
|
||||
//}
|
||||
public void testClassNoDiscardTypesByRef() throws Exception {
|
||||
loadCodeAndRun(getAboveComment());
|
||||
checkNoErrorsOfKind(ER_ID);
|
||||
}
|
||||
|
||||
//struct [[nodiscard]] error_type { error_type(int) {} };
|
||||
//template<class T>
|
||||
//typename T::E foo() {return static_cast<typename T::E>(0);}
|
||||
//template<class F>
|
||||
//struct trait { typedef typename F E; }
|
||||
//void f1() {
|
||||
// foo<trait<error_type>>();
|
||||
//}
|
||||
public void testClassNoDiscardTypesTemplate() throws Exception {
|
||||
CPPASTNameBase.sAllowNameComputation = true;
|
||||
loadCodeAndRun(getAboveComment());
|
||||
checkNoErrorsOfKind(ER_ID);
|
||||
}
|
||||
|
||||
//enum [[nodiscard]] error_type { FAILURE };
|
||||
//error_type enable_missile_safety_mode();
|
||||
//void launch_missiles();
|
||||
//void test_missiles() {
|
||||
// enable_missile_safety_mode();
|
||||
// launch_missiles();
|
||||
//}
|
||||
public void testEnumNoDiscardType() throws Exception {
|
||||
loadCodeAndRun(getAboveComment());
|
||||
checkErrorLine(5, ER_ID);
|
||||
}
|
||||
|
||||
//enum [[nodiscard]] error_type { FAILURE };
|
||||
//error_type& foo();
|
||||
//void f1() {
|
||||
// foo();
|
||||
//}
|
||||
public void testEnumNoDiscardTypesByRef() throws Exception {
|
||||
loadCodeAndRun(getAboveComment());
|
||||
checkNoErrorsOfKind(ER_ID);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue