Merge pull request #1661 from dave-bartolomeo/dave/ExternDeclarations

C++: Stop generating `NoOp` instructions for declarations of externs
This commit is contained in:
zlaski-semmle
2019-07-31 19:09:06 -07:00
committed by GitHub
4 changed files with 67 additions and 10 deletions

View File

@@ -47,7 +47,7 @@ abstract class TranslatedDeclarationEntry extends TranslatedElement, TTranslated
/**
* Represents the IR translation of a declaration within the body of a function,
* for declarations other than local variables. Since these have no semantic
* effect, they are translated as `NoOp`.
* effect, they do not generate any instructions.
*/
class TranslatedNonVariableDeclarationEntry extends TranslatedDeclarationEntry {
TranslatedNonVariableDeclarationEntry() {
@@ -56,14 +56,11 @@ class TranslatedNonVariableDeclarationEntry extends TranslatedDeclarationEntry {
override predicate hasInstruction(Opcode opcode, InstructionTag tag,
Type resultType, boolean isGLValue) {
opcode instanceof Opcode::NoOp and
tag = OnlyInstructionTag() and
resultType instanceof VoidType and
isGLValue = false
none()
}
override Instruction getFirstInstruction() {
result = getInstruction(OnlyInstructionTag())
result = getParent().getChildSuccessor(this)
}
override TranslatedElement getChild(int id) {
@@ -71,10 +68,8 @@ class TranslatedNonVariableDeclarationEntry extends TranslatedDeclarationEntry {
}
override Instruction getInstructionSuccessor(InstructionTag tag,
EdgeKind kind) {
tag = OnlyInstructionTag() and
result = getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
EdgeKind kind) {
none()
}
override Instruction getChildSuccessor(TranslatedElement child) {

View File

@@ -7828,3 +7828,40 @@ ir.cpp:
# 1109| Type = [LValueReferenceType] unsigned int &
# 1109| ValueCategory = prvalue(load)
# 1111| 1: [ReturnStmt] return ...
# 1113| [TopLevelFunction] void ExternDeclarations()
# 1113| params:
# 1114| body: [Block] { ... }
# 1115| 0: [DeclStmt] declaration
# 1115| 0: [VariableDeclarationEntry] declaration of g
# 1115| Type = [IntType] int
# 1116| 1: [DeclStmt] declaration
# 1116| 0: [VariableDeclarationEntry] definition of x
# 1116| Type = [IntType] int
# 1117| 2: [DeclStmt] declaration
# 1117| 0: [VariableDeclarationEntry] definition of y
# 1117| Type = [IntType] int
# 1117| 1: [FunctionDeclarationEntry] declaration of f
# 1117| Type = [IntType] int
# 1118| 3: [DeclStmt] declaration
# 1118| 0: [FunctionDeclarationEntry] declaration of z
# 1118| Type = [IntType] int
# 1118| 1: [FunctionDeclarationEntry] declaration of w
# 1118| Type = [IntType] int
# 1118| 2: [VariableDeclarationEntry] definition of h
# 1118| Type = [IntType] int
# 1119| 4: [DeclStmt] declaration
# 1119| 0: [TypeDeclarationEntry] declaration of d
# 1119| Type = [LocalTypedefType] d
# 1120| 5: [ReturnStmt] return ...
# 1117| [TopLevelFunction] int f(float)
# 1117| params:
# 1117| 0: [Parameter] p#0
# 1117| Type = [FloatType] float
# 1118| [TopLevelFunction] int z(float)
# 1118| params:
# 1118| 0: [Parameter] p#0
# 1118| Type = [FloatType] float
# 1118| [TopLevelFunction] int w(float)
# 1118| params:
# 1118| 0: [Parameter] p#0
# 1118| Type = [FloatType] float

View File

@@ -1110,4 +1110,13 @@ static void AsmStmtWithOutputs(unsigned int& a, unsigned int& b, unsigned int& c
);
}
void ExternDeclarations()
{
extern int g;
int x;
int y, f(float);
int z(float), w(float), h;
typedef double d;
}
// semmle-extractor-options: -std=c++17

View File

@@ -5112,3 +5112,19 @@ ir.cpp:
# 1104| v0_17(void) = ReturnVoid :
# 1104| v0_18(void) = UnmodeledUse : mu*
# 1104| v0_19(void) = ExitFunction :
# 1113| void ExternDeclarations()
# 1113| Block 0
# 1113| v0_0(void) = EnterFunction :
# 1113| mu0_1(unknown) = AliasedDefinition :
# 1113| mu0_2(unknown) = UnmodeledDefinition :
# 1116| r0_3(glval<int>) = VariableAddress[x] :
# 1116| mu0_4(int) = Uninitialized[x] : &:r0_3
# 1117| r0_5(glval<int>) = VariableAddress[y] :
# 1117| mu0_6(int) = Uninitialized[y] : &:r0_5
# 1118| r0_7(glval<int>) = VariableAddress[h] :
# 1118| mu0_8(int) = Uninitialized[h] : &:r0_7
# 1120| v0_9(void) = NoOp :
# 1113| v0_10(void) = ReturnVoid :
# 1113| v0_11(void) = UnmodeledUse : mu*
# 1113| v0_12(void) = ExitFunction :