diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -864,6 +864,8 @@ /// Determine whether this expression refers to a flexible array member in a /// struct. We disable array bounds checks for such members. static bool isFlexibleArrayMemberExpr(const Expr *E) { + // E->dump(); + // For compatibility with existing code, we treat arrays of length 0 or // 1 as flexible array members. // FIXME: This is inconsistent with the warning code in SemaChecking. Unify @@ -877,8 +879,16 @@ } else if (!isa(AT)) return false; + E->dump(); E = E->IgnoreParens(); + while (const BinaryOperator *BO = dyn_cast(E)) { + if (!BO->isCommaOp()) + break; + E = BO->getRHS(); + E = E->IgnoreParens(); + } + // A flexible array member must be the last member in the class. if (const auto *ME = dyn_cast(E)) { // FIXME: If the base type of the member expr is not FD->getParent(), diff --git a/clang/test/CodeGen/bounds-checking.c b/clang/test/CodeGen/bounds-checking.c --- a/clang/test/CodeGen/bounds-checking.c +++ b/clang/test/CodeGen/bounds-checking.c @@ -100,3 +100,19 @@ return s->a[i]; // CHECK: } } + +// CHECK-LABEL: define {{.*}} @SFlexComma +int SFlexComma(struct SFlex *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return (s->t, s->a)[i]; + // CHECK: } +} + +// CHECK-LABEL: define {{.*}} @S1Comma +int S1Comma(struct S1 *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return (s->t, s->a)[i]; + // CHECK: } +} diff --git a/clang/test/CodeGen/bounds-checking.cpp b/clang/test/CodeGen/bounds-checking.cpp --- a/clang/test/CodeGen/bounds-checking.cpp +++ b/clang/test/CodeGen/bounds-checking.cpp @@ -98,3 +98,19 @@ return s->a[i]; // CHECK: } } + +// CHECK-LABEL: define {{.*}} @_Z10SFlexComma +int SFlexComma(struct SFlex *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return (s->t, s->a)[i]; + // CHECK: } +} + +// CHECK-LABEL: define {{.*}} @_Z7S1Comma +int S1Comma(struct S1 *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return ((s->t, (1, s->a)))[i]; + // CHECK: } +}