Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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