Skip to content

Commit 23b74b5

Browse files
author
Robert Marsh
authored
Merge pull request #1750 from dave-bartolomeo/dave/ZooKeeper
C++: Minimal IR support for `GNUVectorType`
2 parents ff20a2c + a84a7e8 commit 23b74b5

File tree

26 files changed

+447
-143
lines changed

26 files changed

+447
-143
lines changed

cpp/ql/src/semmle/code/cpp/exprs/BuiltInOperations.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import semmle.code.cpp.exprs.Expr
44
* A C/C++ builtin operation.
55
*/
66
abstract class BuiltInOperation extends Expr {
7+
override string getCanonicalQLClass() { result = "BuiltInOperation" }
78
}
89

910
/**

cpp/ql/src/semmle/code/cpp/exprs/Literal.qll

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -234,16 +234,33 @@ class ClassAggregateLiteral extends AggregateLiteral {
234234
}
235235

236236
/**
237-
* A C/C++ aggregate literal that initializes an array
237+
* A C/C++ aggregate literal that initializes an array or a GNU vector type.
238238
*/
239-
class ArrayAggregateLiteral extends AggregateLiteral {
240-
ArrayType arrayType;
239+
class ArrayOrVectorAggregateLiteral extends AggregateLiteral {
240+
ArrayOrVectorAggregateLiteral() {
241+
exists(DerivedType type |
242+
type = this.getUnspecifiedType() and
243+
(
244+
type instanceof ArrayType or
245+
type instanceof GNUVectorType
246+
)
247+
)
248+
}
241249

242-
ArrayAggregateLiteral() {
243-
arrayType = this.getUnspecifiedType()
250+
/**
251+
* Gets the number of elements initialized by this initializer list, either explicitly with an
252+
* expression, or by implicit value initialization.
253+
*/
254+
int getArraySize() {
255+
none()
244256
}
245257

246-
override string getCanonicalQLClass() { result = "ArrayAggregateLiteral" }
258+
/**
259+
* Gets the type of the elements in the initializer list.
260+
*/
261+
Type getElementType() {
262+
none()
263+
}
247264

248265
/**
249266
* Gets the expression within the aggregate literal that is used to initialize
@@ -262,7 +279,7 @@ class ArrayAggregateLiteral extends AggregateLiteral {
262279
bindingset[elementIndex]
263280
predicate isInitialized(int elementIndex) {
264281
elementIndex >= 0 and
265-
elementIndex < arrayType.getArraySize()
282+
elementIndex < getArraySize()
266283
}
267284

268285
/**
@@ -279,3 +296,45 @@ class ArrayAggregateLiteral extends AggregateLiteral {
279296
not exists(getElementExpr(elementIndex))
280297
}
281298
}
299+
300+
/**
301+
* A C/C++ aggregate literal that initializes an array
302+
*/
303+
class ArrayAggregateLiteral extends ArrayOrVectorAggregateLiteral {
304+
ArrayType arrayType;
305+
306+
ArrayAggregateLiteral() {
307+
arrayType = this.getUnspecifiedType()
308+
}
309+
310+
override string getCanonicalQLClass() { result = "ArrayAggregateLiteral" }
311+
312+
override int getArraySize() {
313+
result = arrayType.getArraySize()
314+
}
315+
316+
override Type getElementType() {
317+
result = arrayType.getBaseType()
318+
}
319+
}
320+
321+
/**
322+
* A C/C++ aggregate literal that initializes a GNU vector type.
323+
*/
324+
class VectorAggregateLiteral extends ArrayOrVectorAggregateLiteral {
325+
GNUVectorType vectorType;
326+
327+
VectorAggregateLiteral() {
328+
vectorType = this.getUnspecifiedType()
329+
}
330+
331+
override string getCanonicalQLClass() { result = "VectorAggregateLiteral" }
332+
333+
override int getArraySize() {
334+
result = vectorType.getNumElements()
335+
}
336+
337+
override Type getElementType() {
338+
result = vectorType.getBaseType()
339+
}
340+
}

cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ private newtype TOpcode =
5757
TUnmodeledUse() or
5858
TAliasedDefinition() or
5959
TPhi() or
60+
TBuiltIn() or
6061
TVarArgsStart() or
6162
TVarArgsEnd() or
6263
TVarArg() or
@@ -115,7 +116,7 @@ abstract class CatchOpcode extends Opcode {}
115116

116117
abstract class OpcodeWithCondition extends Opcode {}
117118

118-
abstract class BuiltInOpcode extends Opcode {}
119+
abstract class BuiltInOperationOpcode extends Opcode {}
119120

120121
abstract class SideEffectOpcode extends Opcode {}
121122

@@ -204,10 +205,11 @@ module Opcode {
204205
class UnmodeledUse extends Opcode, TUnmodeledUse { override final string toString() { result = "UnmodeledUse" } }
205206
class AliasedDefinition extends Opcode, TAliasedDefinition { override final string toString() { result = "AliasedDefinition" } }
206207
class Phi extends Opcode, TPhi { override final string toString() { result = "Phi" } }
207-
class VarArgsStart extends BuiltInOpcode, TVarArgsStart { override final string toString() { result = "VarArgsStart" } }
208-
class VarArgsEnd extends BuiltInOpcode, TVarArgsEnd { override final string toString() { result = "VarArgsEnd" } }
209-
class VarArg extends BuiltInOpcode, TVarArg { override final string toString() { result = "VarArg" } }
210-
class VarArgCopy extends BuiltInOpcode, TVarArgCopy { override final string toString() { result = "VarArgCopy" } }
208+
class BuiltIn extends BuiltInOperationOpcode, TBuiltIn { override final string toString() { result = "BuiltIn" } }
209+
class VarArgsStart extends BuiltInOperationOpcode, TVarArgsStart { override final string toString() { result = "VarArgsStart" } }
210+
class VarArgsEnd extends BuiltInOperationOpcode, TVarArgsEnd { override final string toString() { result = "VarArgsEnd" } }
211+
class VarArg extends BuiltInOperationOpcode, TVarArg { override final string toString() { result = "VarArg" } }
212+
class VarArgCopy extends BuiltInOperationOpcode, TVarArgCopy { override final string toString() { result = "VarArgCopy" } }
211213
class CallSideEffect extends MayWriteSideEffectOpcode, TCallSideEffect { override final string toString() { result = "CallSideEffect" } }
212214
class CallReadSideEffect extends ReadSideEffectOpcode, TCallReadSideEffect { override final string toString() { result = "CallReadSideEffect" } }
213215
class IndirectReadSideEffect extends ReadSideEffectOpcode, MemoryAccessOpcode, TIndirectReadSideEffect { override final string toString() { result = "IndirectReadSideEffect" } }

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ module InstructionSanity {
7171
operand.getOperandTag() = tag) and
7272
not expectsOperand(instr, tag) and
7373
not (instr instanceof CallInstruction and tag instanceof ArgumentOperandTag) and
74-
not (instr instanceof BuiltInInstruction and tag instanceof PositionalArgumentOperandTag) and
74+
not (instr instanceof BuiltInOperationInstruction and tag instanceof PositionalArgumentOperandTag) and
7575
not (instr instanceof InlineAsmInstruction and tag instanceof AsmOperandTag)
7676
}
7777

@@ -1831,8 +1831,29 @@ class UnreachedInstruction extends Instruction {
18311831
* An instruction representing a built-in operation. This is used to represent
18321832
* operations such as access to variable argument lists.
18331833
*/
1834-
class BuiltInInstruction extends Instruction {
1834+
class BuiltInOperationInstruction extends Instruction {
1835+
Language::BuiltInOperation operation;
1836+
1837+
BuiltInOperationInstruction() {
1838+
getOpcode() instanceof BuiltInOperationOpcode and
1839+
operation = Construction::getInstructionBuiltInOperation(this)
1840+
}
1841+
1842+
final Language::BuiltInOperation getBuiltInOperation() {
1843+
result = operation
1844+
}
1845+
}
1846+
1847+
/**
1848+
* An instruction representing a built-in operation that does not have a specific opcode. The
1849+
* actual operation is specified by the `getBuiltInOperation()` predicate.
1850+
*/
1851+
class BuiltInInstruction extends BuiltInOperationInstruction {
18351852
BuiltInInstruction() {
1836-
getOpcode() instanceof BuiltInOpcode
1853+
getOpcode() instanceof Opcode::BuiltIn
1854+
}
1855+
1856+
override final string getImmediateString() {
1857+
result = getBuiltInOperation().toString()
18371858
}
18381859
}

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,10 @@ cached private module Cached {
325325
result = getOldInstruction(instruction).(OldIR::StringConstantInstruction).getValue()
326326
}
327327

328+
cached BuiltInOperation getInstructionBuiltInOperation(Instruction instruction) {
329+
result = getOldInstruction(instruction).(OldIR::BuiltInOperationInstruction).getBuiltInOperation()
330+
}
331+
328332
cached Type getInstructionExceptionType(Instruction instruction) {
329333
result = getOldInstruction(instruction).(OldIR::CatchByTypeInstruction).getExceptionType()
330334
}

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ module InstructionSanity {
7171
operand.getOperandTag() = tag) and
7272
not expectsOperand(instr, tag) and
7373
not (instr instanceof CallInstruction and tag instanceof ArgumentOperandTag) and
74-
not (instr instanceof BuiltInInstruction and tag instanceof PositionalArgumentOperandTag) and
74+
not (instr instanceof BuiltInOperationInstruction and tag instanceof PositionalArgumentOperandTag) and
7575
not (instr instanceof InlineAsmInstruction and tag instanceof AsmOperandTag)
7676
}
7777

@@ -1831,8 +1831,29 @@ class UnreachedInstruction extends Instruction {
18311831
* An instruction representing a built-in operation. This is used to represent
18321832
* operations such as access to variable argument lists.
18331833
*/
1834-
class BuiltInInstruction extends Instruction {
1834+
class BuiltInOperationInstruction extends Instruction {
1835+
Language::BuiltInOperation operation;
1836+
1837+
BuiltInOperationInstruction() {
1838+
getOpcode() instanceof BuiltInOperationOpcode and
1839+
operation = Construction::getInstructionBuiltInOperation(this)
1840+
}
1841+
1842+
final Language::BuiltInOperation getBuiltInOperation() {
1843+
result = operation
1844+
}
1845+
}
1846+
1847+
/**
1848+
* An instruction representing a built-in operation that does not have a specific opcode. The
1849+
* actual operation is specified by the `getBuiltInOperation()` predicate.
1850+
*/
1851+
class BuiltInInstruction extends BuiltInOperationInstruction {
18351852
BuiltInInstruction() {
1836-
getOpcode() instanceof BuiltInOpcode
1853+
getOpcode() instanceof Opcode::BuiltIn
1854+
}
1855+
1856+
override final string getImmediateString() {
1857+
result = getBuiltInOperation().toString()
18371858
}
18381859
}

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,12 @@ cached private module Cached {
250250
getInstructionTag(instruction))
251251
}
252252

253+
cached BuiltInOperation getInstructionBuiltInOperation(Instruction instruction) {
254+
result =
255+
getInstructionTranslatedElement(instruction).getInstructionBuiltInOperation(
256+
getInstructionTag(instruction))
257+
}
258+
253259
cached Type getInstructionExceptionType(Instruction instruction) {
254260
result =
255261
getInstructionTranslatedElement(instruction).getInstructionExceptionType(

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ newtype TTranslatedElement =
274274
exists(ClassAggregateLiteral initList |
275275
initList.getFieldExpr(_).getFullyConverted() = expr
276276
) or
277-
exists(ArrayAggregateLiteral initList |
277+
exists(ArrayOrVectorAggregateLiteral initList |
278278
initList.getElementExpr(_).getFullyConverted() = expr
279279
) or
280280
exists(ReturnStmt returnStmt |
@@ -320,13 +320,13 @@ newtype TTranslatedElement =
320320
} or
321321
// The initialization of an array element via a member of an initializer list.
322322
TTranslatedExplicitElementInitialization(
323-
ArrayAggregateLiteral initList, int elementIndex) {
323+
ArrayOrVectorAggregateLiteral initList, int elementIndex) {
324324
not ignoreExpr(initList) and
325325
exists(initList.getElementExpr(elementIndex))
326326
} or
327327
// The value initialization of a range of array elements that were omitted
328328
// from an initializer list.
329-
TTranslatedElementValueInitialization(ArrayAggregateLiteral initList,
329+
TTranslatedElementValueInitialization(ArrayOrVectorAggregateLiteral initList,
330330
int elementIndex, int elementCount) {
331331
not ignoreExpr(initList) and
332332
isFirstValueInitializedElementInRange(initList, elementIndex) and
@@ -412,12 +412,13 @@ newtype TTranslatedElement =
412412
* `initList`, the result is the total number of elements in the array being
413413
* initialized.
414414
*/
415-
private int getEndOfValueInitializedRange(ArrayAggregateLiteral initList, int afterElementIndex) {
415+
private int getEndOfValueInitializedRange(ArrayOrVectorAggregateLiteral initList,
416+
int afterElementIndex) {
416417
result = getNextExplicitlyInitializedElementAfter(initList, afterElementIndex)
417418
or
418419
isFirstValueInitializedElementInRange(initList, afterElementIndex) and
419420
not exists(getNextExplicitlyInitializedElementAfter(initList, afterElementIndex)) and
420-
result = initList.getUnspecifiedType().(ArrayType).getArraySize()
421+
result = initList.getArraySize()
421422
}
422423

423424
/**
@@ -427,7 +428,7 @@ private int getEndOfValueInitializedRange(ArrayAggregateLiteral initList, int af
427428
* `initList`.
428429
*/
429430
private int getNextExplicitlyInitializedElementAfter(
430-
ArrayAggregateLiteral initList, int afterElementIndex) {
431+
ArrayOrVectorAggregateLiteral initList, int afterElementIndex) {
431432
isFirstValueInitializedElementInRange(initList, afterElementIndex) and
432433
result = min(int i | exists(initList.getElementExpr(i)) and i > afterElementIndex)
433434
}
@@ -437,7 +438,7 @@ private int getNextExplicitlyInitializedElementAfter(
437438
* range of one or more consecutive value-initialized elements in `initList`.
438439
*/
439440
private predicate isFirstValueInitializedElementInRange(
440-
ArrayAggregateLiteral initList, int elementIndex) {
441+
ArrayOrVectorAggregateLiteral initList, int elementIndex) {
441442
initList.isValueInitialized(elementIndex) and
442443
(
443444
elementIndex = 0 or
@@ -634,6 +635,13 @@ abstract class TranslatedElement extends TTranslatedElement {
634635
none()
635636
}
636637

638+
/**
639+
* If the instruction specified by `tag` is a `BuiltInInstruction`, gets the built-in operation.
640+
*/
641+
BuiltInOperation getInstructionBuiltInOperation(InstructionTag tag) {
642+
none()
643+
}
644+
637645
/**
638646
* If the instruction specified by `tag` is a `CatchByTypeInstruction`,
639647
* gets the type of the exception to be caught.

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -612,10 +612,15 @@ class TranslatedPostfixCrementOperation extends TranslatedCrementOperation {
612612
}
613613
}
614614

615+
/**
616+
* IR translation of an array access expression (e.g. `a[i]`). The array being accessed will either
617+
* be a prvalue of pointer type (possibly due to an implicit array-to-pointer conversion), or a
618+
* glvalue of a GNU vector type.
619+
*/
615620
class TranslatedArrayExpr extends TranslatedNonConstantExpr {
616621
override ArrayExpr expr;
617622

618-
override Instruction getFirstInstruction() {
623+
override final Instruction getFirstInstruction() {
619624
result = getBaseOperand().getFirstInstruction()
620625
}
621626

@@ -650,8 +655,8 @@ class TranslatedArrayExpr extends TranslatedNonConstantExpr {
650655
Type resultType, boolean isGLValue) {
651656
tag = OnlyInstructionTag() and
652657
opcode instanceof Opcode::PointerAdd and
653-
resultType = getBaseOperand().getResultType() and
654-
isGLValue = false
658+
resultType = getResultType() and
659+
isGLValue = true
655660
}
656661

657662
override Instruction getInstructionOperand(InstructionTag tag,
@@ -671,7 +676,7 @@ class TranslatedArrayExpr extends TranslatedNonConstantExpr {
671676

672677
override int getInstructionElementSize(InstructionTag tag) {
673678
tag = OnlyInstructionTag() and
674-
result = max(getBaseOperand().getResultType().(PointerType).getBaseType().getSize())
679+
result = max(getResultType().getSize())
675680
}
676681

677682
private TranslatedExpr getBaseOperand() {
@@ -2373,7 +2378,13 @@ class TranslatedReThrowExpr extends TranslatedThrowExpr {
23732378
* The IR translation of a built-in operation (i.e. anything that extends
23742379
* `BuiltInOperation`).
23752380
*/
2376-
abstract class TranslatedBuiltInOperation extends TranslatedNonConstantExpr {
2381+
class TranslatedBuiltInOperation extends TranslatedNonConstantExpr {
2382+
override BuiltInOperation expr;
2383+
2384+
TranslatedBuiltInOperation() {
2385+
not expr instanceof BuiltInOperationBuiltInAddressOf // Handled specially
2386+
}
2387+
23772388
override final Instruction getResult() {
23782389
result = getInstruction(OnlyInstructionTag())
23792390
}
@@ -2423,7 +2434,14 @@ abstract class TranslatedBuiltInOperation extends TranslatedNonConstantExpr {
24232434
)
24242435
}
24252436

2426-
abstract Opcode getOpcode();
2437+
Opcode getOpcode() {
2438+
result instanceof Opcode::BuiltIn
2439+
}
2440+
2441+
override final BuiltInOperation getInstructionBuiltInOperation(InstructionTag tag) {
2442+
tag = OnlyInstructionTag() and
2443+
result = expr
2444+
}
24272445
}
24282446

24292447
/**

0 commit comments

Comments
 (0)