|
| 1 | +/** |
| 2 | + * @name Implicit Void Ptr to Typed Ptr promotion |
| 3 | + * @description Implicit conversion from void* to a typed pointer |
| 4 | + * @kind problem |
| 5 | + * @problem.severity recommendation |
| 6 | + * @precision high |
| 7 | + * @id firedancer-io/implicit-void-promotion |
| 8 | + */ |
| 9 | + |
| 10 | +import cpp |
| 11 | + |
| 12 | +class VoidPointer extends PointerType { |
| 13 | + VoidPointer() { this.getBaseType().getUnspecifiedType() instanceof VoidType } |
| 14 | +} |
| 15 | + |
| 16 | +predicate implicitVoidPromotion(Type lvalue, Type rvalue) { |
| 17 | + not lvalue.getUnderlyingType() instanceof VoidPointer and |
| 18 | + rvalue.getUnderlyingType() instanceof VoidPointer |
| 19 | +} |
| 20 | + |
| 21 | +predicate allowedSourceFile(File file) { file.getBaseName() != "fd_types.c" } |
| 22 | + |
| 23 | +class BroadAssign extends Locatable { |
| 24 | + BroadAssign() { this instanceof Variable or this instanceof AssignExpr } |
| 25 | + |
| 26 | + Expr getRExpr() { |
| 27 | + result = this.(Variable).getInitializer().getExpr() or |
| 28 | + result = this.(AssignExpr).getRValue() |
| 29 | + } |
| 30 | + |
| 31 | + Type getLType() { |
| 32 | + result = this.(Variable).getType() or |
| 33 | + result = this.(AssignExpr).getLValue().getType() |
| 34 | + } |
| 35 | + |
| 36 | + Type getRType() { result = this.getRExpr().getType() } |
| 37 | +} |
| 38 | + |
| 39 | +from BroadAssign assign |
| 40 | +where |
| 41 | + implicitVoidPromotion(assign.getLType(), assign.getRType()) and |
| 42 | + allowedSourceFile(assign.getLocation().getFile()) and |
| 43 | + not assign.getRExpr().isInMacroExpansion() and |
| 44 | + not assign.getRExpr().hasExplicitConversion() and |
| 45 | + not assign.getRExpr().(FunctionCall).getTarget().getName().matches("fd_type_pun%") |
| 46 | +select assign, "Implicit conversion from void * to " + assign.getLType() |
0 commit comments