r192674 - Sema: Consider it an error to apply __builtin_offsetof to a member in a virtual base

David Majnemer david.majnemer at gmail.com
Mon Oct 14 23:28:23 PDT 2013


Author: majnemer
Date: Tue Oct 15 01:28:23 2013
New Revision: 192674

URL: http://llvm.org/viewvc/llvm-project?rev=192674&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/SemaCXX/offsetof.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=192674&r1=192673&r2=192674&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Oct 15 01:28:23 2013
@@ -4200,6 +4200,8 @@ def warn_offsetof_non_pod_type : ExtWarn
 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 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<PointerArith>;

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=192674&r1=192673&r2=192674&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Oct 15 01:28:23 2013
@@ -9996,9 +9996,15 @@ ExprResult Sema::BuildBuiltinOffsetOf(So
 
     // 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)

Modified: cfe/trunk/test/SemaCXX/offsetof.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/offsetof.cpp?rev=192674&r1=192673&r2=192674&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/offsetof.cpp (original)
+++ cfe/trunk/test/SemaCXX/offsetof.cpp Tue Oct 15 01:28:23 2013
@@ -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}}
+};
+}





More information about the cfe-commits mailing list