]> granicus.if.org Git - clang/commitdiff
PR7769: Fix references to anonymous structs/unions in base classes in
authorEli Friedman <eli.friedman@gmail.com>
Thu, 5 Aug 2010 10:11:36 +0000 (10:11 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Thu, 5 Aug 2010 10:11:36 +0000 (10:11 +0000)
offsetof expressions.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110327 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/SemaCXX/offsetof.cpp

index 6799da1ab68b5522f76166ef661e50a8f3513831..80274e1a6bc9786cbcabbfb2b0ff34b08a920ae2 100644 (file)
@@ -6940,22 +6940,27 @@ Sema::OwningExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
       Diag(MemberDecl->getLocation(), diag::note_bitfield_decl);
       return ExprError();
     }
-      
+
+    RecordDecl *Parent = MemberDecl->getParent();
+    bool AnonStructUnion = Parent->isAnonymousStructOrUnion();
+    if (AnonStructUnion) {
+      do {
+        Parent = cast<RecordDecl>(Parent->getParent());
+      } while (Parent->isAnonymousStructOrUnion());
+    }
+
     // If the member was found in a base class, introduce OffsetOfNodes for
     // the base class indirections.
     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
                        /*DetectVirtual=*/false);
-    if (IsDerivedFrom(CurrentType, 
-                      Context.getTypeDeclType(MemberDecl->getParent()), 
-                      Paths)) {
+    if (IsDerivedFrom(CurrentType, Context.getTypeDeclType(Parent), Paths)) {
       CXXBasePath &Path = Paths.front();
       for (CXXBasePath::iterator B = Path.begin(), BEnd = Path.end();
            B != BEnd; ++B)
         Comps.push_back(OffsetOfNode(B->Base));
     }
-    
-    if (cast<RecordDecl>(MemberDecl->getDeclContext())->
-                                                isAnonymousStructOrUnion()) {
+
+    if (AnonStructUnion) {
       llvm::SmallVector<FieldDecl*, 4> Path;
       BuildAnonymousStructUnionMemberPath(MemberDecl, Path);
       unsigned n = Path.size();
index 639d7faa8e96f5625e80f9c989c49b157fcff37c..17cee62d16fc8051637ad069c8b81d6203317ab6 100644 (file)
@@ -53,3 +53,16 @@ struct Derived2 : public Base1, public Base2 {
 int derived1[__builtin_offsetof(Derived2, x) == 0? 1 : -1];
 int derived2[__builtin_offsetof(Derived2, y)  == 4? 1 : -1];
 int derived3[__builtin_offsetof(Derived2, z)  == 8? 1 : -1];
+
+// offsetof referring to anonymous struct in base.
+// PR7769
+struct foo {
+    struct {
+        int x;
+    };
+};
+
+struct bar : public foo  {
+};
+
+int anonstruct[__builtin_offsetof(bar, x) == 0 ? 1 : -1];