From: Eli Friedman Date: Fri, 4 Dec 2009 07:18:51 +0000 (+0000) Subject: Make sure to call PerformObjectMemberConversion where necessary. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=16c5378c1e3af09a33604e096b3fe20742fc629d;p=clang Make sure to call PerformObjectMemberConversion where necessary. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90555 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 895f9305ff..da1fe3d44d 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -605,6 +605,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, MemberType = Context.getQualifiedType(MemberType, NewQuals); MarkDeclarationReferenced(Loc, *FI); + PerformObjectMemberConversion(Result, *FI); // FIXME: Might this end up being a qualified name? Result = new (Context) MemberExpr(Result, BaseObjectIsPointer, *FI, OpLoc, MemberType); @@ -2397,7 +2398,8 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType, if (FieldDecl *FD = dyn_cast(MemberDecl)) { // We may have found a field within an anonymous union or struct // (C++ [class.union]). - if (cast(FD->getDeclContext())->isAnonymousStructOrUnion()) + if (cast(FD->getDeclContext())->isAnonymousStructOrUnion() && + !BaseType->getAs()->getDecl()->isAnonymousStructOrUnion()) return BuildAnonymousStructUnionMemberReference(MemberLoc, FD, BaseExpr, OpLoc); @@ -6397,6 +6399,7 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S, Res = BuildAnonymousStructUnionMemberReference( OC.LocEnd, MemberDecl, Res, OC.LocEnd).takeAs(); } else { + PerformObjectMemberConversion(Res, MemberDecl); // MemberDecl->getType() doesn't get the right qualifiers, but it // doesn't matter here. Res = new (Context) MemberExpr(Res, false, MemberDecl, OC.LocEnd, diff --git a/test/SemaCXX/member-expr-anonymous-union.cpp b/test/SemaCXX/member-expr-anonymous-union.cpp new file mode 100644 index 0000000000..9566df4a20 --- /dev/null +++ b/test/SemaCXX/member-expr-anonymous-union.cpp @@ -0,0 +1,9 @@ +// RUN: clang-cc %s -fsyntax-only -verify +// PR5543 + +struct A { int x; union { int* y; float& z; }; }; struct B : A {int a;}; +int* a(B* x) { return x->y; } + +struct x { union { int y; }; }; x y; template int f() { return X+y.y; } +int g() { return f<2>(); } + diff --git a/test/SemaCXX/offsetof.cpp b/test/SemaCXX/offsetof.cpp index f0290e889a..e18987f11a 100644 --- a/test/SemaCXX/offsetof.cpp +++ b/test/SemaCXX/offsetof.cpp @@ -13,3 +13,6 @@ void f() { int i = __builtin_offsetof(P, fieldThatPointsToANonPODType.m); // expected-warning{{offset of on non-POD type 'struct P'}} } +struct Base { int x; }; +struct Derived : Base { int y; }; +int o = __builtin_offsetof(Derived, x); // expected-warning{{offset of on non-POD type}}