[Clang] Fix crash when checking misaligned member with dependent type
authorJun Zhang <jun@junz.org>
Tue, 18 Oct 2022 12:38:30 +0000 (20:38 +0800)
committerJun Zhang <jun@junz.org>
Tue, 18 Oct 2022 13:05:49 +0000 (21:05 +0800)
If the type is dependent, we should just discard it and not checking its
alignment as it doesn't exisit yet.
Fixes https://github.com/llvm/llvm-project/issues/58370

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

clang/lib/Sema/SemaChecking.cpp
clang/test/SemaCXX/misaligned-member-with-depdent-type.cpp [new file with mode: 0644]

index c0ecd7b..9d8640a 100644 (file)
@@ -17387,15 +17387,15 @@ void Sema::DiagnoseMisalignedMembers() {
 
 void Sema::DiscardMisalignedMemberAddress(const Type *T, Expr *E) {
   E = E->IgnoreParens();
-  if (!T->isPointerType() && !T->isIntegerType())
+  if (!T->isPointerType() && !T->isIntegerType() && !T->isDependentType())
     return;
   if (isa<UnaryOperator>(E) &&
       cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf) {
     auto *Op = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
     if (isa<MemberExpr>(Op)) {
-      auto MA = llvm::find(MisalignedMembers, MisalignedMember(Op));
+      auto *MA = llvm::find(MisalignedMembers, MisalignedMember(Op));
       if (MA != MisalignedMembers.end() &&
-          (T->isIntegerType() ||
+          (T->isDependentType() || T->isIntegerType() ||
            (T->isPointerType() && (T->getPointeeType()->isIncompleteType() ||
                                    Context.getTypeAlignInChars(
                                        T->getPointeeType()) <= MA->Alignment))))
diff --git a/clang/test/SemaCXX/misaligned-member-with-depdent-type.cpp b/clang/test/SemaCXX/misaligned-member-with-depdent-type.cpp
new file mode 100644 (file)
index 0000000..cd47683
--- /dev/null
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct __attribute__((packed)) {
+  unsigned options;
+  template <typename T>
+  void getOptions() {
+      (T *)&options;
+  }
+  template <typename U>
+       void getOptions2() {
+      (U)&options;
+       }
+} s;
+
+struct __attribute__((packed)) { // expected-error {{anonymous structs and classes must be class members}}
+           unsigned options ;
+  template <typename T> getOptions() // expected-error {{a type specifier is required for all declarations}}
+    {
+      (T *) & options;
+    }
+};