Skip to content

C/C++: Compilation failure with 2.21.0 #19266

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
xryj920 opened this issue Apr 9, 2025 · 5 comments
Closed

C/C++: Compilation failure with 2.21.0 #19266

xryj920 opened this issue Apr 9, 2025 · 5 comments
Labels
question Further information is requested

Comments

@xryj920
Copy link

xryj920 commented Apr 9, 2025

Description of the issue
I am trying:codeql query run call_graph_3.ql --database=/data/yujie/tools/CKGFuzzer-main/docker shared/codeqldb/curl 3 --output=/data/yujie/tools/CKGFuzzer-main/fuzzing llm engine/external_database/curl/codebase/call graph/ src curlpackages_0s400_os400sys.c@Curl_ldap_err2string_a_call_graph.bars

How to solve this?Thanks!!!

ERROR: could not resolve module Function (/data/yuiie/tools/CKGFuzzer-main/dockershared/qlpacks/cpp queries/call graph 3.ql:3,8-16)ERROR: could not resolve type DataFlow::configuration (/data/yujie/tools/CKGFuzZer-main/docker shared/qlpacks/cpp queries/call graph 3.ql:6,20-43)ERROR: getFullsignature()cannot be resolved for type Function::Function (/datayujie/tools/CKGFuzzer-main/docker shared/qlpacks/cpp queries/call graph 3.ql:959-25)ERROR: getFullSignature()cannot be resolved for type Function: :Function (/datavuiie/tools/CKGFuzzer-main/docker shared/alpacks/cpp queries/call graph 3.al.997-23)ERROR: DataFlowPrivate::DataFlowcallable is incompatible with Function::Function(/data/yujie/tools/CKGFuzzer-main/docker shared/qlpacks/cpp queries/call graph3.ql:41.33-34)

@xryj920 xryj920 added the question Further information is requested label Apr 9, 2025
@xryj920
Copy link
Author

xryj920 commented Apr 9, 2025

I am using CodeQL Bundle v2.21.0

@smowton
Copy link
Contributor

smowton commented Apr 9, 2025

Can you please post the call_graph_3.ql file that is failing to compile?

@xryj920
Copy link
Author

xryj920 commented Apr 9, 2025

Of course!

import cpp
import semmle.code.cpp.ir.dataflow.DataFlow

// Configuration for function pointer calls
class Conf extends DataFlow::Configuration {
  Conf() { this = "Conf" }

  override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof FunctionAccess }

  override predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(ExprCall call).getExpr() }
}

// Direct function calls
predicate directCall(Function caller, Function callee) {
  exists(FunctionCall fc |
    fc.getEnclosingFunction() = caller and
    fc.getTarget() = callee
  )
}

// Virtual method calls
predicate virtualCall(Function caller, Function callee) {
  exists(Call vc |
    vc.getEnclosingFunction() = caller and
    vc.getTarget() = callee and
    exists(MemberFunction mf |  
      mf = callee and
      exists(MemberFunction base |
        base = mf.getAnOverriddenFunction*() and
        base.isVirtual()
      )
    )
  )
}

// Function pointer calls
predicate functionPointerCall(Function caller, Function callee) {
  exists(FunctionAccess funcAccess, DataFlow::Node sink |
    any(Conf conf).hasFlow(DataFlow::exprNode(funcAccess), sink) and
    sink.getEnclosingCallable() = caller and
    callee = funcAccess.getTarget()
  )
}

// Combined edge predicate
predicate edges(Function caller, Function callee) {
  directCall(caller, callee) or
  virtualCall(caller, callee) or
  functionPointerCall(caller, callee)
}

// Reachability predicate (includes transitive calls)
predicate reachable(Function src, Function dest) {
  edges(src, dest)
  or
  exists(Function mid |
    edges(src, mid) and
    reachable(mid, dest)
  )
}

// Entry point predicate
predicate isEntryPoint(Function f) {
  f.hasName("main") or
  f.hasName("Curl_ldap_err2string_a") or
  exists(Function func |
    func = f and
    (
      exists(Class c | 
        c.getAMember() = func and 
        func.getName() = c.getName()
      ) or
      not exists(Class c | c.getAMember() = func)
    )
  )
}

// Main query
from Function start, Function end, Location start_loc, Location end_loc
where
  isEntryPoint(start) and
  reachable(start, end) and
  start_loc = start.getLocation() and
  end_loc = end.getLocation()
select
  start as caller,
  end as callee,
  start.getFile() as caller_src,
  end.getFile() as callee_src,
  start_loc.getStartLine() as start_body_start_line,
  start_loc.getEndLine() as start_body_end_line,
  end_loc.getStartLine() as end_body_start_line,
  end_loc.getEndLine() as end_body_end_line,
  start.getFullSignature() as caller_signature,
  start.getParameterString() as caller_parameter_string,
  start.getType() as caller_return_type,
  start.getUnspecifiedType() as caller_return_type_inferred,
  end.getFullSignature() as callee_signature,
  end.getParameterString() as callee_parameter_string,
  end.getType() as callee_return_type,
  end.getUnspecifiedType() as callee_return_type_inferred

@smowton
Copy link
Contributor

smowton commented Apr 9, 2025

The old configuration-class data-flow interface has been removed; it is replaced by a module-based scheme.

class Conf extends DataFlow::Configuration {
  Conf() { this = "Conf" }

  override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof FunctionAccess }

  override predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(ExprCall call).getExpr() }
}

should become

module Conf implements DataFlow::ConfigSig {
  predicate isSource(DataFlow::Node source) { source.asExpr() instanceof FunctionAccess }

  predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(ExprCall call).getExpr() }
}

module ConfFlow = DataFlow::Global<Conf>;

and replace

    any(Conf conf).hasFlow(DataFlow::exprNode(funcAccess), sink) and
    sink.getEnclosingCallable() = caller and

with

    ConfFlow::flow(DataFlow::exprNode(funcAccess), sink) and
    sink.getEnclosingCallable().asSourceCallable() = caller and

Secondly, the getFullSignature predicate has been removed. Instead, import semmle.code.cpp.Print and use getIdentityString(start) and similar.

With these changes applied, the QL once again compiles. Full result:

import cpp
import semmle.code.cpp.ir.dataflow.DataFlow
import semmle.code.cpp.Print

// Configuration for function pointer calls
module Conf implements DataFlow::ConfigSig {
  predicate isSource(DataFlow::Node source) { source.asExpr() instanceof FunctionAccess }

  predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(ExprCall call).getExpr() }
}

module ConfFlow = DataFlow::Global<Conf>;

// Direct function calls
predicate directCall(Function caller, Function callee) {
  exists(FunctionCall fc |
    fc.getEnclosingFunction() = caller and
    fc.getTarget() = callee
  )
}

// Virtual method calls
predicate virtualCall(Function caller, Function callee) {
  exists(Call vc |
    vc.getEnclosingFunction() = caller and
    vc.getTarget() = callee and
    exists(MemberFunction mf |  
      mf = callee and
      exists(MemberFunction base |
        base = mf.getAnOverriddenFunction*() and
        base.isVirtual()
      )
    )
  )
}

// Function pointer calls
predicate functionPointerCall(Function caller, Function callee) {
  exists(FunctionAccess funcAccess, DataFlow::Node sink |
    ConfFlow::flow(DataFlow::exprNode(funcAccess), sink) and
    sink.getEnclosingCallable().asSourceCallable() = caller and
    callee = funcAccess.getTarget()
  )
}

// Combined edge predicate
predicate edges(Function caller, Function callee) {
  directCall(caller, callee) or
  virtualCall(caller, callee) or
  functionPointerCall(caller, callee)
}

// Reachability predicate (includes transitive calls)
predicate reachable(Function src, Function dest) {
  edges(src, dest)
  or
  exists(Function mid |
    edges(src, mid) and
    reachable(mid, dest)
  )
}

// Entry point predicate
predicate isEntryPoint(Function f) {
  f.hasName("main") or
  f.hasName("Curl_ldap_err2string_a") or
  exists(Function func |
    func = f and
    (
      exists(Class c | 
        c.getAMember() = func and 
        func.getName() = c.getName()
      ) or
      not exists(Class c | c.getAMember() = func)
    )
  )
}

// Main query
from Function start, Function end, Location start_loc, Location end_loc
where
  isEntryPoint(start) and
  reachable(start, end) and
  start_loc = start.getLocation() and
  end_loc = end.getLocation()
select
  start as caller,
  end as callee,
  start.getFile() as caller_src,
  end.getFile() as callee_src,
  start_loc.getStartLine() as start_body_start_line,
  start_loc.getEndLine() as start_body_end_line,
  end_loc.getStartLine() as end_body_start_line,
  end_loc.getEndLine() as end_body_end_line,
  getIdentityString(start) as caller_signature,
  start.getParameterString() as caller_parameter_string,
  start.getType() as caller_return_type,
  start.getUnspecifiedType() as caller_return_type_inferred,
  getIdentityString(end) as callee_signature,
  end.getParameterString() as callee_parameter_string,
  end.getType() as callee_return_type,
  end.getUnspecifiedType() as callee_return_type_inferred

@smowton smowton changed the title codeql query issue:could not resolve C/C++: Compilation failure with 2.21.0 Apr 9, 2025
@xryj920
Copy link
Author

xryj920 commented Apr 10, 2025

Thanks!!

@smowton smowton closed this as completed Apr 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants