aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2009-12-04 07:18:51 +0000
committerEli Friedman <eli.friedman@gmail.com>2009-12-04 07:18:51 +0000
commit16c5378c1e3af09a33604e096b3fe20742fc629d (patch)
tree9667e08e2cbc8ae46bb7a66ea346833e9da165e6
parent2e77aa1c2a596b66d436d27b8ec2ea695cf9a748 (diff)
Make sure to call PerformObjectMemberConversion where necessary.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90555 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaExpr.cpp5
-rw-r--r--test/SemaCXX/member-expr-anonymous-union.cpp9
-rw-r--r--test/SemaCXX/offsetof.cpp3
3 files changed, 16 insertions, 1 deletions
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<FieldDecl>(MemberDecl)) {
// We may have found a field within an anonymous union or struct
// (C++ [class.union]).
- if (cast<RecordDecl>(FD->getDeclContext())->isAnonymousStructOrUnion())
+ if (cast<RecordDecl>(FD->getDeclContext())->isAnonymousStructOrUnion() &&
+ !BaseType->getAs<RecordType>()->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<Expr>();
} 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 X> 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}}