C++: Fix another implicit/explicit this FP

This commit is contained in:
Nora Dimitrijević 2022-09-29 18:42:23 +02:00
Родитель 28bd591107
Коммит 891bc342be
2 изменённых файлов: 31 добавлений и 8 удалений

Просмотреть файл

@ -11,12 +11,35 @@
import cpp
import semmle.code.cpp.commons.Exclusions
/**
* Holds if this is an implicit `this`.
*
* ThisExpr.isCompilerGenerated() is currently not being extracted, so use a heuristic.
*/
predicate isCompilerGenerated(ThisExpr te) {
exists(
string filepath, int line, int colStart, int colEnd, boolean zeroDiff, boolean sameLocAsCall
|
te.getLocation().hasLocationInfo(filepath, line, colStart, line, colEnd) and
(if colStart = colEnd then zeroDiff = true else zeroDiff = false) and
(
if exists(Call c | c.getQualifier() = te | c.getLocation() = te.getLocation())
then sameLocAsCall = true
else sameLocAsCall = false
)
|
zeroDiff = true
or
zeroDiff = false and sameLocAsCall = true
)
}
/** Gets the sub-expression of 'e' with the earliest-starting Location */
Expr normalizeExpr(Expr e) {
if forex(Expr q | q = e.(Call).getQualifier() | not q.(ThisExpr).isCompilerGenerated())
if forex(Expr q | q = e.(Call).getQualifier() | not isCompilerGenerated(q.(ThisExpr)))
then result = normalizeExpr(e.(Call).getQualifier())
else
if forex(Expr q | q = e.(FieldAccess).getQualifier() | not q.(ThisExpr).isCompilerGenerated())
if forex(Expr q | q = e.(FieldAccess).getQualifier() | not isCompilerGenerated(q.(ThisExpr)))
then result = normalizeExpr(e.(FieldAccess).getQualifier())
else
if e.hasExplicitConversion()

Просмотреть файл

@ -16,7 +16,7 @@ struct X {
#define BAZ //printf
struct Foo {
int i;
int i, i_array[3];
int j;
virtual int foo(int) = 0;
virtual int bar(int, int) = 0;
@ -27,9 +27,9 @@ struct Foo {
void tutu() {}
long toto() { return 42; }
} titi;
} *tata;
Tata::Titi **titi_ptr_ptr;
Titi *operator->() { return &titi; }
} *tata;
};
int Foo::test(int (*baz)(int))
@ -38,7 +38,7 @@ int Foo::test(int (*baz)(int))
if (i)
(void)i, // GOOD
(void)j;
j++;
if (i)
this->foo(i), // GOOD
@ -181,8 +181,8 @@ int Foo::test(int (*baz)(int))
(tata->titi.tutu(),
foo(tata->titi.toto())); // GOOD
(*titi_ptr_ptr)->tutu(), // GOOD
(&i)[0] += (int)(*titi_ptr_ptr)->toto();
(*tata)->toto(), // GOOD
i_array[i] += (int)(*tata)->toto();
return quux;
}