Skip to content

Commit

Permalink
Go: Add BasicBlock.getLocation
Browse files Browse the repository at this point in the history
  • Loading branch information
hvitved committed Feb 17, 2025
1 parent b08f535 commit f72e1f6
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 134 deletions.
95 changes: 61 additions & 34 deletions go/ql/lib/semmle/go/Locations.qll
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@
import go
private import internal.Locations

private module DbLocationInput implements LocationClassInputSig {
class Base = TDbLocation;

predicate locationInfo(
Base b, string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
exists(File f |
dbLocationInfo(b, f, startline, startcolumn, endline, endcolumn) and
filepath = f.getAbsolutePath()
)
}

File getFile(Base b) { dbLocationInfo(b, result, _, _, _, _) }
}

/**
* A location as given by a file, a start line, a start column,
* an end line, and an end column.
Expand All @@ -11,51 +26,63 @@ private import internal.Locations
*
* For more information about locations see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
class DbLocation extends TDbLocation {
/** Gets the file for this location. */
File getFile() { dbLocationInfo(this, result, _, _, _, _) }
class DbLocation = LocationClass<DbLocationInput>::Location;

/** Gets the 1-based line number (inclusive) where this location starts. */
int getStartLine() { dbLocationInfo(this, _, result, _, _, _) }
private module DbOrBasicBlockLocationInput implements LocationClassInputSig {
class Base = TDbLocation or TBasicBlockLocation;

/** Gets the 1-based column number (inclusive) where this location starts. */
int getStartColumn() { dbLocationInfo(this, _, _, result, _, _) }
predicate locationInfo(
Base b, string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
DbLocationInput::locationInfo(b, filepath, startline, startcolumn, endline, endcolumn)
or
basicBlockLocationInfo(b, filepath, startline, startcolumn, endline, endcolumn)
}

/** Gets the 1-based line number (inclusive) where this location ends. */
int getEndLine() { dbLocationInfo(this, _, _, _, result, _) }
File getFile(Base b) {
result = DbLocationInput::getFile(b)
or
basicBlockLocationInfo(b, result.getAbsolutePath(), _, _, _, _)
}
}

/** Gets the 1-based column number (inclusive) where this location ends. */
int getEndColumn() { dbLocationInfo(this, _, _, _, _, result) }
/**
* A location as given by a file, a start line, a start column,
* an end line, and an end column.
*
* This class is restricted to locations created by the extractor or
* synthesized for basic blocks.
*
* For more information about locations see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
class DbOrBasicBlockLocation = LocationClass<DbOrBasicBlockLocationInput>::Location;

/** Gets the number of lines covered by this location. */
int getNumLines() { result = this.getEndLine() - this.getStartLine() + 1 }
private module LocationInput implements LocationClassInputSig {
class Base = TLocation;

/** Gets a textual representation of this element. */
string toString() {
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
this.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
result = filepath + "@" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
)
predicate locationInfo(
Base b, string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
DbOrBasicBlockLocationInput::locationInfo(b, filepath, startline, startcolumn, endline,
endcolumn)
or
dataFlowNodeLocationInfo(b, filepath, startline, startcolumn, endline, endcolumn)
}

/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
exists(File f |
dbLocationInfo(this, f, startline, startcolumn, endline, endcolumn) and
filepath = f.getAbsolutePath()
)
File getFile(Base b) {
result = DbOrBasicBlockLocationInput::getFile(b)
or
dataFlowNodeLocationInfo(b, result.getAbsolutePath(), _, _, _, _)
}
}

final class Location = LocationImpl;
/**
* A location as given by a file, a start line, a start column,
* an end line, and an end column.
*
* For more information about locations see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
class Location = LocationClass<LocationInput>::Location;

/** A program element with a location. */
class Locatable extends @locatable {
Expand Down
9 changes: 6 additions & 3 deletions go/ql/lib/semmle/go/controlflow/BasicBlocks.qll
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import go
private import ControlFlowGraphImpl
private import semmle.go.internal.Locations

/**
* Holds if `nd` starts a new basic block.
Expand Down Expand Up @@ -121,12 +122,14 @@ class BasicBlock extends TControlFlowNode {
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
deprecated predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getFirstNode().hasLocationInfo(filepath, startline, startcolumn, _, _) and
this.getLastNode().hasLocationInfo(_, _, _, endline, endcolumn)
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}

/** Gets the location of this basic block. */
DbOrBasicBlockLocation getLocation() { result = getBasicBlockLocation(this) }
}

/**
Expand Down
4 changes: 2 additions & 2 deletions go/ql/lib/semmle/go/dataflow/SSA.qll
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ abstract class SsaImplicitDefinition extends SsaDefinition {
) {
endline = startline and
endcolumn = startcolumn and
this.getBasicBlock().hasLocationInfo(filepath, startline, startcolumn, _, _)
this.getBasicBlock().getLocation().hasLocationInfo(filepath, startline, startcolumn, _, _)
}
}

Expand Down Expand Up @@ -298,7 +298,7 @@ class SsaPhiNode extends SsaPseudoDefinition, TPhi {
) {
endline = startline and
endcolumn = startcolumn and
this.getBasicBlock().hasLocationInfo(filepath, startline, startcolumn, _, _)
this.getBasicBlock().getLocation().hasLocationInfo(filepath, startline, startcolumn, _, _)
}
}

Expand Down
8 changes: 2 additions & 6 deletions go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ private import semmle.go.dataflow.FlowSummary
private import DataFlowPrivate
private import FlowSummaryImpl as FlowSummaryImpl
private import semmle.go.dataflow.ExternalFlow
private import semmle.go.internal.Locations

cached
private newtype TNode =
Expand Down Expand Up @@ -158,12 +159,7 @@ module Public {
}

/** Gets the location of this node. */
Location getLocation() {
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
this.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
result.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
)
}
Location getLocation() { result = getDataFlowNodeLocation(this) }

/** Gets the file in which this node appears. */
File getFile() { this.hasLocationInfo(result.getAbsolutePath(), _, _, _, _) }
Expand Down
Loading

0 comments on commit f72e1f6

Please sign in to comment.