Skip to content

Commit

Permalink
Revert "Revert "[analyzer] Ignore IncompleteArrayTypes in getStaticSi…
Browse files Browse the repository at this point in the history
…ze() for FAMs""

This reverts commit df1f4e0.

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
  • Loading branch information
Balazs Benics committed Aug 25, 2021
1 parent 5f848b3 commit e5646b9
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 5 deletions.
23 changes: 18 additions & 5 deletions clang/lib/StaticAnalyzer/Core/MemRegion.cpp
Expand Up @@ -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;
}
Expand Down
96 changes: 96 additions & 0 deletions clang/test/Analysis/flexible-array-members.c
@@ -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);
}

0 comments on commit e5646b9

Please sign in to comment.