diff --git a/ql/src/codeql_ql/style/RedundantInlineCastQuery.qll b/ql/src/codeql_ql/style/RedundantInlineCastQuery.qll new file mode 100644 index 00000000000..2f349fc94a0 --- /dev/null +++ b/ql/src/codeql_ql/style/RedundantInlineCastQuery.qll @@ -0,0 +1,35 @@ +import ql + +class RedundantInlineCast extends AstNode instanceof InlineCast { + Type t; + + RedundantInlineCast() { + t = unique( | | super.getType()) and + ( + // The cast is to the type the base expression already has + t = unique( | | super.getBase().getType()) + or + // The cast is to the same type as the other expression in an equality comparison + exists(ComparisonFormula comp, Expr other | comp.getOperator() = "=" | + this = comp.getAnOperand() and + other = comp.getAnOperand() and + this != other and + t = unique( | | other.getType()) and + not other instanceof InlineCast // we don't want to risk both sides being "redundant" + ) + or + exists(Call call, int i, Predicate target | + this = call.getArgument(i) and + target = unique( | | call.getTarget()) and + t = unique( | | target.getParameterType(i)) + ) + ) and + // noopt can require explicit casts + not exists(Annotation annon | annon = this.getEnclosingPredicate().getAnAnnotation() | + annon.getName() = "pragma" and + annon.getArgs(0).getValue() = "noopt" + ) + } + + TypeExpr getTypeExpr() { result = super.getTypeExpr() } +} diff --git a/ql/src/queries/style/RedundantInlineCast.ql b/ql/src/queries/style/RedundantInlineCast.ql new file mode 100644 index 00000000000..29dc83e52de --- /dev/null +++ b/ql/src/queries/style/RedundantInlineCast.ql @@ -0,0 +1,16 @@ +/** + * @name Redundant inline cast + * @description Redundant inline casts + * @kind problem + * @problem.severity error + * @id ql/redundant-inline-cast + * @tags maintainability + * @precision high + */ + +import ql +import codeql_ql.style.RedundantInlineCastQuery + +from RedundantInlineCast cast +select cast, "Redundant cast to $@", cast.getTypeExpr(), + cast.getTypeExpr().getResolvedType().getName()