forked from OSchip/llvm-project
Revert "Revert "[analyzer] Ignore IncompleteArrayTypes in getStaticSize() for FAMs""
This reverts commit df1f4e0cc6
.
Now the test case explicitly specifies the target triple.
I decided to use x86_64 for that matter, to have a fixed
bitwidth for `size_t`.
Aside from that, relanding the original changes of:
https://reviews.llvm.org/D105184
This commit is contained in:
parent
5f848b311f
commit
e5646b9254
|
@ -768,14 +768,27 @@ DefinedOrUnknownSVal MemRegionManager::getStaticSize(const MemRegion *MR,
|
|||
return UnknownVal();
|
||||
|
||||
QualType Ty = cast<TypedValueRegion>(SR)->getDesugaredValueType(Ctx);
|
||||
DefinedOrUnknownSVal Size = getElementExtent(Ty, SVB);
|
||||
const DefinedOrUnknownSVal Size = getElementExtent(Ty, SVB);
|
||||
|
||||
// A zero-length array at the end of a struct often stands for dynamically
|
||||
// allocated extra memory.
|
||||
if (Size.isZeroConstant()) {
|
||||
if (isa<ConstantArrayType>(Ty))
|
||||
return UnknownVal();
|
||||
const auto isFlexibleArrayMemberCandidate = [this](QualType Ty) -> bool {
|
||||
const ArrayType *AT = Ctx.getAsArrayType(Ty);
|
||||
if (!AT)
|
||||
return false;
|
||||
if (isa<IncompleteArrayType>(AT))
|
||||
return true;
|
||||
|
||||
if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
|
||||
const llvm::APInt &Size = CAT->getSize();
|
||||
if (Size.isNullValue())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if (isFlexibleArrayMemberCandidate(Ty))
|
||||
return UnknownVal();
|
||||
|
||||
return Size;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
// RUN: %clang_analyze_cc1 -triple x86_64-linux-gnu -analyzer-checker=core,unix,debug.ExprInspection %s -verify -std=c90
|
||||
// RUN: %clang_analyze_cc1 -triple x86_64-linux-gnu -analyzer-checker=core,unix,debug.ExprInspection %s -verify -std=c99
|
||||
// RUN: %clang_analyze_cc1 -triple x86_64-linux-gnu -analyzer-checker=core,unix,debug.ExprInspection %s -verify -std=c11
|
||||
// RUN: %clang_analyze_cc1 -triple x86_64-linux-gnu -analyzer-checker=core,unix,debug.ExprInspection %s -verify -std=c17
|
||||
|
||||
// RUN: %clang_analyze_cc1 -triple x86_64-linux-gnu -analyzer-checker=core,unix,debug.ExprInspection %s -verify -std=c++98 -x c++
|
||||
// RUN: %clang_analyze_cc1 -triple x86_64-linux-gnu -analyzer-checker=core,unix,debug.ExprInspection %s -verify -std=c++03 -x c++
|
||||
// RUN: %clang_analyze_cc1 -triple x86_64-linux-gnu -analyzer-checker=core,unix,debug.ExprInspection %s -verify -std=c++11 -x c++
|
||||
// RUN: %clang_analyze_cc1 -triple x86_64-linux-gnu -analyzer-checker=core,unix,debug.ExprInspection %s -verify -std=c++14 -x c++
|
||||
// RUN: %clang_analyze_cc1 -triple x86_64-linux-gnu -analyzer-checker=core,unix,debug.ExprInspection %s -verify -std=c++17 -x c++
|
||||
|
||||
typedef __typeof(sizeof(int)) size_t;
|
||||
size_t clang_analyzer_getExtent(void *);
|
||||
void clang_analyzer_dump(size_t);
|
||||
|
||||
void *alloca(size_t size);
|
||||
void *malloc(size_t size);
|
||||
void free(void *ptr);
|
||||
|
||||
void test_incomplete_array_fam() {
|
||||
typedef struct FAM {
|
||||
char c;
|
||||
int data[];
|
||||
} FAM;
|
||||
|
||||
FAM fam;
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(&fam));
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(fam.data));
|
||||
// expected-warning@-2 {{4 S64b}}
|
||||
// expected-warning@-2 {{Unknown}}
|
||||
|
||||
FAM *p = (FAM *)alloca(sizeof(FAM));
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(p));
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(p->data));
|
||||
// expected-warning@-2 {{4 U64b}}
|
||||
// expected-warning@-2 {{Unknown}}
|
||||
|
||||
FAM *q = (FAM *)malloc(sizeof(FAM));
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(q));
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(q->data));
|
||||
// expected-warning@-2 {{4 U64b}}
|
||||
// expected-warning@-2 {{Unknown}}
|
||||
free(q);
|
||||
}
|
||||
|
||||
void test_zero_length_array_fam() {
|
||||
typedef struct FAM {
|
||||
char c;
|
||||
int data[0];
|
||||
} FAM;
|
||||
|
||||
FAM fam;
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(&fam));
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(fam.data));
|
||||
// expected-warning@-2 {{4 S64b}}
|
||||
// expected-warning@-2 {{Unknown}}
|
||||
|
||||
FAM *p = (FAM *)alloca(sizeof(FAM));
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(p));
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(p->data));
|
||||
// expected-warning@-2 {{4 U64b}}
|
||||
// expected-warning@-2 {{Unknown}}
|
||||
|
||||
FAM *q = (FAM *)malloc(sizeof(FAM));
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(q));
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(q->data));
|
||||
// expected-warning@-2 {{4 U64b}}
|
||||
// expected-warning@-2 {{Unknown}}
|
||||
free(q);
|
||||
}
|
||||
|
||||
void test_single_element_array_possible_fam() {
|
||||
typedef struct FAM {
|
||||
char c;
|
||||
int data[1];
|
||||
} FAM;
|
||||
|
||||
FAM likely_fam;
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(&likely_fam));
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(likely_fam.data));
|
||||
// expected-warning@-2 {{8 S64b}}
|
||||
// expected-warning@-2 {{4 S64b}}
|
||||
|
||||
FAM *p = (FAM *)alloca(sizeof(FAM));
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(p));
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(p->data));
|
||||
// expected-warning@-2 {{8 U64b}}
|
||||
// expected-warning@-2 {{4 S64b}}
|
||||
|
||||
FAM *q = (FAM *)malloc(sizeof(FAM));
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(q));
|
||||
clang_analyzer_dump(clang_analyzer_getExtent(q->data));
|
||||
// expected-warning@-2 {{8 U64b}}
|
||||
// expected-warning@-2 {{4 S64b}}
|
||||
free(q);
|
||||
}
|
Loading…
Reference in New Issue