InGroup<DiagGroup<"extended-offsetof">>;
def warn_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">,
InGroup<InvalidOffsetof>;
+def warn_offsetof_non_standardlayout_type : ExtWarn<
+ "offset of on non-standard-layout type %0">, InGroup<InvalidOffsetof>;
def err_offsetof_bitfield : Error<"cannot compute offset of bit-field %0">;
def warn_floatingpoint_eq : Warning<
// 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<CXXRecordDecl>(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;
--- /dev/null
+// 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