Author: Balazs Benics
Date: 2021-08-25T17:19:06+02:00
New Revision: e5646b9254e0150e7897bd2658fa0b19eef39070

URL: 
https://github.com/llvm/llvm-project/commit/e5646b9254e0150e7897bd2658fa0b19eef39070
DIFF: 
https://github.com/llvm/llvm-project/commit/e5646b9254e0150e7897bd2658fa0b19eef39070.diff

LOG: Revert "Revert "[analyzer] Ignore IncompleteArrayTypes in getStaticSize() 
for FAMs""

This reverts commit df1f4e0cc6ec9a734aae41ffd48ee8b2007fcabb.

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

Added: 
    clang/test/Analysis/flexible-array-members.c

Modified: 
    clang/lib/StaticAnalyzer/Core/MemRegion.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp 
b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
index bd725ee9eaa36..1a614d4d2bcdb 100644
--- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -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;
   }

diff  --git a/clang/test/Analysis/flexible-array-members.c 
b/clang/test/Analysis/flexible-array-members.c
new file mode 100644
index 0000000000000..6200ed6d41d27
--- /dev/null
+++ b/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);
+}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to