From ebbbc9c7fc40acc88e1f6967b0d7d469b0f31a5e Mon Sep 17 00:00:00 2001
From: Olivier Goffart <ogoffart@woboq.com>
Date: Fri, 7 Jul 2017 09:38:59 +0000
Subject: [PATCH] Fix crash parsing invalid code

The code in the test caused a crash with this backtrace:

 RecordLayoutBuilder.cpp:2934: const clang::ASTRecordLayout &clang::ASTContext::getASTRecordLayout(const clang::RecordDecl *) const: Assertion `!D->isInvalidDecl() && "Cannot get layout of invalid decl!"' failed.
 [...]
 #7 0x00007f63963d845a __assert_fail_base (/usr/lib/libc.so.6+0x2c45a)
 #8 0x00007f63963d84d2 (/usr/lib/libc.so.6+0x2c4d2)
 #9 0x00007f63937a0631 clang::ASTContext::getASTRecordLayout(clang::RecordDecl const*) const /home/olivier/prog/llvm/tools/clang/lib/AST/RecordLayoutBuilder.cpp:2935:3
 #10 0x00007f63937a1ad5 getFieldOffset(clang::ASTContext const&, clang::FieldDecl const*) /home/olivier/prog/llvm/tools/clang/lib/AST/RecordLayoutBuilder.cpp:3057:37
 #11 0x00007f6391869f14 clang::Sema::RefersToMemberWithReducedAlignment(clang::Expr*, llvm::function_ref<void (clang::Expr*, clang::RecordDecl*, clang::FieldDecl*, clang::CharUnits)>) /home/olivier/prog/llvm/tools/clang/lib/Sema/SemaChecking.cpp:12139:23
 #12 0x00007f639186a2f8 clang::Sema::CheckAddressOfPackedMember(clang::Expr*) /home/olivier/prog/llvm/tools/clang/lib/Sema/SemaChecking.cpp:12190:1
 #13 0x00007f6391a7a81c clang::Sema::CheckAddressOfOperand(clang::ActionResult<clang::Expr*, true>&, clang::SourceLocation) /home/olivier/prog/llvm/tools/clang/lib/Sema/SemaExpr.cpp:11111:10
 #14 0x00007f6391a7f5d2 clang::Sema::CreateBuiltinUnaryOp(clang::SourceLocation, clang::UnaryOperatorKind, clang::Expr*) /home/olivier/prog/llvm/tools/clang/lib/Sema/SemaExpr.cpp:11932:18

Fixing by bailing out for invalid classes.

Differential Revision: https://reviews.llvm.org/D35108

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@307371 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaChecking.cpp  | 2 ++
 test/Sema/address-packed.c | 9 +++++++++
 2 files changed, 11 insertions(+)

diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 41dafa82ca1..8446601334e 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -12097,6 +12097,8 @@ void Sema::RefersToMemberWithReducedAlignment(
     if (ME->isArrow())
       BaseType = BaseType->getPointeeType();
     RecordDecl *RD = BaseType->getAs<RecordType>()->getDecl();
+    if (RD->isInvalidDecl())
+      return;
 
     ValueDecl *MD = ME->getMemberDecl();
     auto *FD = dyn_cast<FieldDecl>(MD);
diff --git a/test/Sema/address-packed.c b/test/Sema/address-packed.c
index 2799e19c48f..b0519bacd75 100644
--- a/test/Sema/address-packed.c
+++ b/test/Sema/address-packed.c
@@ -329,3 +329,12 @@ void g13(void) {
   uint32_t *p32;
   p32 = &a[0].x; // no-warning
 }
+
+struct Invalid0 {
+  void *x;
+  struct fwd f; // expected-error {{incomplete type}} expected-note {{forward declaration}}
+} __attribute__((packed));
+
+void *g14(struct Invalid0 *ivl) {
+  return &(ivl->x);
+}
-- 
GitLab