Skip to content

Commit f757ecb

Browse files
committed
[AST] Fix a crash on invalid bitwidth exprs when preserving the recoveryexprs.
Summary: If the bitwith expr contains errors, we mark the field decl invalid. This patch also tweaks the behavior of ObjCInterfaceDecl to be consistent with existing RecordDecl -- getObjCLayout method is only called with valid decls. Reviewers: sammccall Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D76953
1 parent dcc04e0 commit f757ecb

File tree

4 files changed

+24
-1
lines changed

4 files changed

+24
-1
lines changed

clang/lib/AST/ASTContext.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2161,6 +2161,11 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
21612161
return getTypeInfo(cast<AdjustedType>(T)->getAdjustedType().getTypePtr());
21622162
case Type::ObjCInterface: {
21632163
const auto *ObjCI = cast<ObjCInterfaceType>(T);
2164+
if (ObjCI->getDecl()->isInvalidDecl()) {
2165+
Width = 8;
2166+
Align = 8;
2167+
break;
2168+
}
21642169
const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
21652170
Width = toBits(Layout.getSize());
21662171
Align = toBits(Layout.getAlignment());

clang/lib/AST/RecordLayoutBuilder.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3222,7 +3222,8 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
32223222
if (D->hasExternalLexicalStorage() && !D->getDefinition())
32233223
getExternalSource()->CompleteType(const_cast<ObjCInterfaceDecl*>(D));
32243224
D = D->getDefinition();
3225-
assert(D && D->isThisDeclarationADefinition() && "Invalid interface decl!");
3225+
assert(D && !D->isInvalidDecl() && D->isThisDeclarationADefinition() &&
3226+
"Invalid interface decl!");
32263227

32273228
// Look up this layout, if already laid out, return what we have.
32283229
const ObjCContainerDecl *Key =

clang/lib/Sema/SemaDecl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16172,6 +16172,10 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
1617216172
IdentifierInfo *FieldName,
1617316173
QualType FieldTy, bool IsMsStruct,
1617416174
Expr *BitWidth, bool *ZeroWidth) {
16175+
assert(BitWidth);
16176+
if (BitWidth->containsErrors())
16177+
return ExprError();
16178+
1617516179
// Default to true; that shouldn't confuse checks for emptiness
1617616180
if (ZeroWidth)
1617716181
*ZeroWidth = true;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %clang_cc1 -fobjc-runtime=gcc -frecovery-ast -verify %s
2+
// RUN: %clang_cc1 -fobjc-runtime=gcc -fno-recovery-ast -verify %s
3+
4+
@interface Ivar
5+
{
6+
int Foo : foo(); // expected-error {{use of undeclared identifier}}
7+
};
8+
@end
9+
10+
struct X { int Y: foo(); }; // expected-error {{use of undeclared identifier}}
11+
12+
constexpr int s = sizeof(Ivar);
13+
constexpr int ss = sizeof(X);

0 commit comments

Comments
 (0)