arphaman created this revision.
arphaman added reviewers: vsapsai, rsmith, george.burgess.iv.

The commit r316245 introduced a regression that causes an assertion failure 
when Clang tries to cast an `IncompleteArrayType` to a `PointerType` when 
evaluating __builtin_object_size in this sample:

  typedef struct         {
    char string[512];
  } NestedArrayStruct;
  
  typedef struct         {
      int x;
      NestedArrayStruct session[];
  } IncompleteArrayStruct;
  
  void func(IncompleteArrayStruct* p) {
     __builtin___strlcpy_chk (p->session[0].string, "ab", 2, 
__builtin_object_size(p->session[0].string, 1));
  }

Interestingly enough gcc seems to produce a different output for the above code 
(when `1` is the last parameter to `__builtin_object_size`). It evaluates 
`__builtin_object_size` to 512 instead of -1 like Clang:

https://godbolt.org/g/vD9F9T

I'm still not sure what's the right behavior after reading GCC's description of 
__builtin_object_size 
(https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html). Maybe someone 
who's more familiar with this builtin could point to the cause of this 
discrepancy.

rdar://36094951


Repository:
  rC Clang

https://reviews.llvm.org/D41405

Files:
  lib/AST/ExprConstant.cpp
  test/Sema/builtin-object-size.c


Index: test/Sema/builtin-object-size.c
===================================================================
--- test/Sema/builtin-object-size.c
+++ test/Sema/builtin-object-size.c
@@ -91,3 +91,16 @@
 
   return n;
 }
+
+typedef struct          {
+  char string[512];
+} NestedArrayStruct;
+
+typedef struct          {
+    int x;
+    NestedArrayStruct  session[];
+} IncompleteArrayStruct;
+
+void rd36094951_IAS_builtin_object_size_assertion(IncompleteArrayStruct* p) {
+   __builtin___strlcpy_chk (p->session[0].string, "ab", 2, 
__builtin_object_size(p->session[0].string, 1));
+}
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -7419,7 +7419,10 @@
     // If we don't know the array bound, conservatively assume we're looking at
     // the final array element.
     ++I;
-    BaseType = BaseType->castAs<PointerType>()->getPointeeType();
+    if (BaseType->isIncompleteArrayType())
+      BaseType = Ctx.getAsArrayType(BaseType)->getElementType();
+    else
+      BaseType = BaseType->castAs<PointerType>()->getPointeeType();
   }
 
   for (unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {


Index: test/Sema/builtin-object-size.c
===================================================================
--- test/Sema/builtin-object-size.c
+++ test/Sema/builtin-object-size.c
@@ -91,3 +91,16 @@
 
   return n;
 }
+
+typedef struct 	 {
+  char string[512];
+} NestedArrayStruct;
+
+typedef struct 	 {
+    int x;
+    NestedArrayStruct	session[];
+} IncompleteArrayStruct;
+
+void rd36094951_IAS_builtin_object_size_assertion(IncompleteArrayStruct* p) {
+   __builtin___strlcpy_chk (p->session[0].string, "ab", 2, __builtin_object_size(p->session[0].string, 1));
+}
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -7419,7 +7419,10 @@
     // If we don't know the array bound, conservatively assume we're looking at
     // the final array element.
     ++I;
-    BaseType = BaseType->castAs<PointerType>()->getPointeeType();
+    if (BaseType->isIncompleteArrayType())
+      BaseType = Ctx.getAsArrayType(BaseType)->getElementType();
+    else
+      BaseType = BaseType->castAs<PointerType>()->getPointeeType();
   }
 
   for (unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to