C++: Impoved alias analysis of smart pointers

This commit is contained in:
Dave Bartolomeo
2021-04-20 19:42:06 -04:00
parent 63fe4fb317
commit a447b049fc
7 changed files with 387 additions and 65 deletions

View File

@@ -5,7 +5,16 @@ private import semmle.code.cpp.ir.internal.IntegerConstant as Ints
private predicate ignoreAllocation(string name) {
name = "i" or
name = "p" or
name = "q"
name = "q" or
name = "s" or
name = "t" or
name = "?{AllAliased}"
}
private predicate ignoreFile(File file) {
// Ignore standard headers.
file.getBaseName() = ["memory.h", "type_traits.h", "utility.h"] or
not file.fromSource()
}
module Raw {
@@ -29,7 +38,8 @@ module Raw {
not ignoreAllocation(memLocation.getAllocation().getAllocationString()) and
value = memLocation.toString() and
element = instr.toString() and
location = instr.getLocation()
location = instr.getLocation() and
not ignoreFile(location.getFile())
)
}
}
@@ -52,13 +62,14 @@ module UnaliasedSSA {
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Instruction instr, MemoryLocation memLocation |
memLocation = getAMemoryAccess(instr) and
not memLocation instanceof AliasedVirtualVariable and
not memLocation.getVirtualVariable() instanceof AliasedVirtualVariable and
not memLocation instanceof AllNonLocalMemory and
tag = "ussa" and
not ignoreAllocation(memLocation.getAllocation().getAllocationString()) and
value = memLocation.toString() and
element = instr.toString() and
location = instr.getLocation()
location = instr.getLocation() and
not ignoreFile(location.getFile())
)
}
}

View File

@@ -0,0 +1,33 @@
#include "../../../include/memory.h"
#include "../../../include/utility.h"
using std::shared_ptr;
using std::unique_ptr;
struct S {
int x;
};
void unique_ptr_init(S s) {
unique_ptr<S> p(new S); //$ussa=dynamic{1}
int i = (*p).x; //$ussa=dynamic{1}[0..4)<int>
*p = s; //$ussa=dynamic{1}[0..4)<S>
unique_ptr<S> q = std::move(p);
*(q.get()) = s; //$ussa=dynamic{1}[0..4)<S>
shared_ptr<S> t(std::move(q));
t->x = 5; //$ussa=dynamic{1}[0..4)<int>
*t = s; //$ussa=dynamic{1}[0..4)<S>
*(t.get()) = s; //$ussa=dynamic{1}[0..4)<S>
}
void shared_ptr_init(S s) {
shared_ptr<S> p(new S); //$ussa=dynamic{1}
int i = (*p).x; //$ussa=dynamic{1}[0..4)<int>
*p = s; //$ussa=dynamic{1}[0..4)<S>
shared_ptr<S> q = std::move(p);
*(q.get()) = s; //$ussa=dynamic{1}[0..4)<S>
shared_ptr<S> t(q);
t->x = 5; //$ussa=dynamic{1}[0..4)<int>
*t = s; //$ussa=dynamic{1}[0..4)<S>
*(t.get()) = s; //$ussa=dynamic{1}[0..4)<S>
}