Fix -fsanitize=array-bound to treat T[0] union members as flexible array

members regardless of whether they're the last member of the union.
This commit is contained in:
Richard Smith 2020-03-18 15:46:31 -07:00
parent 47622efc6f
commit f18233dad4
2 changed files with 28 additions and 2 deletions

View File

@ -866,8 +866,12 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
static bool isFlexibleArrayMemberExpr(const Expr *E) {
// 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
// the two mechanisms.
const ArrayType *AT = E->getType()->castAsArrayTypeUnsafe();
if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
// FIXME: Sema doesn't treat [1] as a flexible array member if the bound
// was produced by macro expansion.
if (CAT->getSize().ugt(1))
return false;
} else if (!isa<IncompleteArrayType>(AT))
@ -880,6 +884,10 @@ static bool isFlexibleArrayMemberExpr(const Expr *E) {
// FIXME: If the base type of the member expr is not FD->getParent(),
// this should not be treated as a flexible array member access.
if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
// FIXME: Sema doesn't treat a T[1] union member as a flexible array
// member, only a T[0] or T[] member gets that treatment.
if (FD->getParent()->isUnion())
return true;
RecordDecl::field_iterator FI(
DeclContext::decl_iterator(const_cast<FieldDecl *>(FD)));
return ++FI == FD->getParent()->field_end();

View File

@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsanitize=local-bounds -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
// RUN: %clang_cc1 -fsanitize=local-bounds -fexperimental-new-pass-manager -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
// RUN: %clang_cc1 -fsanitize=array-bounds -O -fsanitize-trap=array-bounds -emit-llvm -triple x86_64-apple-darwin10 -DNO_DYNAMIC %s -o - | FileCheck %s
// RUN: %clang_cc1 -fsanitize=array-bounds -O -fsanitize-trap=array-bounds -fexperimental-new-pass-manager -emit-llvm -triple x86_64-apple-darwin10 -DNO_DYNAMIC %s -o - | FileCheck %s
// RUN: %clang_cc1 -fsanitize=array-bounds -O -fsanitize-trap=array-bounds -emit-llvm -triple x86_64-apple-darwin10 -DNO_DYNAMIC %s -o - | FileCheck %s --check-prefixes=CHECK,NONLOCAL
// RUN: %clang_cc1 -fsanitize=array-bounds -O -fsanitize-trap=array-bounds -fexperimental-new-pass-manager -emit-llvm -triple x86_64-apple-darwin10 -DNO_DYNAMIC %s -o - | FileCheck %s --check-prefixes=CHECK,NONLOCAL
//
// REQUIRES: x86-registered-target
@ -31,3 +31,21 @@ void f3() {
// CHECK: call {{.*}} @llvm.trap
a[2] = 1;
}
union U { int a[0]; int b[1]; int c[2]; };
// CHECK-LABEL: define {{.*}} @f4
int f4(union U *u, int i) {
// a and b are treated as flexible array members.
// CHECK-NOT: @llvm.trap
return u->a[i] + u->b[i];
// CHECK: }
}
// CHECK-LABEL: define {{.*}} @f5
int f5(union U *u, int i) {
// c is not a flexible array member.
// NONLOCAL: call {{.*}} @llvm.trap
return u->c[i];
// CHECK: }
}