From edb5fdfb732d9b05f7f3c3248edea7b14331f4a4 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Tue, 15 Oct 2013 06:28:23 +0000 Subject: [PATCH] Sema: Consider it an error to apply __builtin_offsetof to a member in a virtual base icc 13 and g++ 4.9 both reject this while we would crash. Fixes PR17578. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192674 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ lib/Sema/SemaExpr.cpp | 10 ++++++++-- test/SemaCXX/offsetof.cpp | 10 ++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 8f68278eeb..1c4f0bc50a 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -4200,6 +4200,8 @@ def warn_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">, def warn_offsetof_non_standardlayout_type : ExtWarn< "offset of on non-standard-layout type %0">, InGroup; def err_offsetof_bitfield : Error<"cannot compute offset of bit-field %0">; +def err_offsetof_field_of_virtual_base : Error< + "invalid application of 'offsetof' to a field of a virtual base">; def warn_sub_ptr_zero_size_types : Warning< "subtraction of pointers to type %0 of zero size has undefined behavior">, InGroup; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 6bcc49ed62..04e01f6ccb 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -9996,9 +9996,15 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, // If the member was found in a base class, introduce OffsetOfNodes for // the base class indirections. - CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, - /*DetectVirtual=*/false); + CXXBasePaths Paths; if (IsDerivedFrom(CurrentType, Context.getTypeDeclType(Parent), Paths)) { + if (Paths.getDetectedVirtual()) { + Diag(OC.LocEnd, diag::err_offsetof_field_of_virtual_base) + << MemberDecl->getDeclName() + << SourceRange(BuiltinLoc, RParenLoc); + return ExprError(); + } + CXXBasePath &Path = Paths.front(); for (CXXBasePath::iterator B = Path.begin(), BEnd = Path.end(); B != BEnd; ++B) diff --git a/test/SemaCXX/offsetof.cpp b/test/SemaCXX/offsetof.cpp index a5f5d347c2..e6069ac9c0 100644 --- a/test/SemaCXX/offsetof.cpp +++ b/test/SemaCXX/offsetof.cpp @@ -73,3 +73,13 @@ struct LtoRCheck { }; int ltor = __builtin_offsetof(struct LtoRCheck, a[LtoRCheck().f]); // \ expected-error {{reference to non-static member function must be called}} + +namespace PR17578 { +struct Base { + int Field; +}; +struct Derived : virtual Base { + void Fun() { (void)__builtin_offsetof(Derived, Field); } // expected-warning {{offset of on non-POD type}} \ + expected-error {{invalid application of 'offsetof' to a field of a virtual base}} +}; +} -- 2.40.0