From: Benjamin Kramer Date: Sat, 28 Apr 2012 11:14:51 +0000 (+0000) Subject: C++11 weakens the requirement for types used with offsetof from POD to standard layou... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=98f71aae339e00bfc7b556a78e2538931198ec9c;p=clang C++11 weakens the requirement for types used with offsetof from POD to standard layout type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155757 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index b53e250f19..cf7de93e01 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -3535,6 +3535,8 @@ def ext_offsetof_extended_field_designator : Extension< InGroup>; def warn_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">, InGroup; +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 warn_floatingpoint_eq : Warning< diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 043a6f7fde..9de08bc309 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -8744,10 +8744,18 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, // The macro offsetof accepts a restricted set of type arguments in this // International Standard. type shall be a POD structure or a POD union // (clause 9). + // C++11 [support.types]p4: + // If type is not a standard-layout class (Clause 9), the results are + // undefined. if (CXXRecordDecl *CRD = dyn_cast(RD)) { - if (!CRD->isPOD() && !DidWarnAboutNonPOD && + bool IsSafe = LangOpts.CPlusPlus0x? CRD->isStandardLayout() : CRD->isPOD(); + unsigned DiagID = + LangOpts.CPlusPlus0x? diag::warn_offsetof_non_standardlayout_type + : diag::warn_offsetof_non_pod_type; + + if (!IsSafe && !DidWarnAboutNonPOD && DiagRuntimeBehavior(BuiltinLoc, 0, - PDiag(diag::warn_offsetof_non_pod_type) + PDiag(DiagID) << SourceRange(CompPtr[0].LocStart, OC.LocEnd) << CurrentType)) DidWarnAboutNonPOD = true; diff --git a/test/SemaCXX/offsetof-0x.cpp b/test/SemaCXX/offsetof-0x.cpp new file mode 100644 index 0000000000..610d919c1a --- /dev/null +++ b/test/SemaCXX/offsetof-0x.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only -std=c++11 -verify %s -Winvalid-offsetof + +struct NonPOD { + virtual void f(); + int m; +}; + +struct P { + NonPOD fieldThatPointsToANonPODType; +}; + +void f() { + int i = __builtin_offsetof(P, fieldThatPointsToANonPODType.m); // expected-warning{{offset of on non-standard-layout type 'P'}} +} + +struct StandardLayout { + int x; + StandardLayout() {} +}; +int o = __builtin_offsetof(StandardLayout, x); // no-warning