From: Ted Kremenek Date: Wed, 9 May 2012 05:35:08 +0000 (+0000) Subject: Teach IsTailPaddedMemberArray() (used by -Warray-bounds) that a FieldDecl may have... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=00e1f6f5fed4f33f67181578be0232accd342282;p=clang Teach IsTailPaddedMemberArray() (used by -Warray-bounds) that a FieldDecl may have a Typedef type, and not always a ConstantArrayType. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156464 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index d538fcf36d..bc4452f125 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -4590,12 +4590,20 @@ static bool IsTailPaddedMemberArray(Sema &S, llvm::APInt Size, // substitution to form C89 tail-padded arrays. TypeSourceInfo *TInfo = FD->getTypeSourceInfo(); - if (TInfo) { - ConstantArrayTypeLoc TL = - cast(TInfo->getTypeLoc()); - const Expr *SizeExpr = dyn_cast(TL.getSizeExpr()); + while (TInfo) { + TypeLoc TL = TInfo->getTypeLoc(); + // Look through typedefs. + const TypedefTypeLoc *TTL = dyn_cast(&TL); + if (TTL) { + const TypedefNameDecl *TDL = TTL->getTypedefNameDecl(); + TInfo = TDL->getTypeSourceInfo(); + continue; + } + ConstantArrayTypeLoc CTL = cast(TL); + const Expr *SizeExpr = dyn_cast(CTL.getSizeExpr()); if (!SizeExpr || SizeExpr->getExprLoc().isMacroID()) return false; + break; } const RecordDecl *RD = dyn_cast(FD->getDeclContext()); diff --git a/test/Sema/array-bounds-ptr-arith.c b/test/Sema/array-bounds-ptr-arith.c index 022335bd37..e3de06a104 100644 --- a/test/Sema/array-bounds-ptr-arith.c +++ b/test/Sema/array-bounds-ptr-arith.c @@ -19,3 +19,21 @@ void pr11594(struct S *s) { int a[10]; int *p = a - s->n; } + +// Test case reduced from . This resulted in +// an assertion failure because of the typedef instead of an explicit +// constant array type. +struct RDar11387038 {}; +typedef struct RDar11387038 RDar11387038Array[1]; +struct RDar11387038_Table { + RDar11387038Array z; +}; +typedef struct RDar11387038_Table * TPtr; +typedef TPtr *TabHandle; +struct RDar11387038_B { TabHandle x; }; +typedef struct RDar11387038_B RDar11387038_B; + +void radar11387038() { + RDar11387038_B *pRDar11387038_B; + struct RDar11387038* y = &(*pRDar11387038_B->x)->z[4]; +}