[cfe-commits] r102548 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp test/Sema/offsetof.c test/SemaCXX/offsetof.cpp

Douglas Gregor dgregor at apple.com
Wed Apr 28 15:36:06 PDT 2010


Author: dgregor
Date: Wed Apr 28 17:36:06 2010
New Revision: 102548

URL: http://llvm.org/viewvc/llvm-project?rev=102548&view=rev
Log:
Diagnose __builtin_offsetof expressions that refer to bit-fields

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/Sema/offsetof.c
    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=102548&r1=102547&r2=102548&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Apr 28 17:36:06 2010
@@ -1817,6 +1817,7 @@
   "using extended field designator is an extension">;
 def warn_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">,
   InGroup<InvalidOffsetof>;
+def err_offsetof_bitfield : Error<"cannot compute offset of bit-field %0">;
 
 def warn_floatingpoint_eq : Warning<
   "comparing floating point with == or != is unsafe">,

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=102548&r1=102547&r2=102548&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Apr 28 17:36:06 2010
@@ -6718,10 +6718,20 @@
                        << OC.U.IdentInfo << RD << SourceRange(OC.LocStart, 
                                                               OC.LocEnd));
     
-    // FIXME: C99 Verify that MemberDecl isn't a bitfield.
-    
+    // C99 7.17p3:
+    //   (If the specified member is a bit-field, the behavior is undefined.)
+    //
+    // We diagnose this as an error.
+    if (MemberDecl->getBitWidth()) {
+      Diag(OC.LocEnd, diag::err_offsetof_bitfield)
+        << MemberDecl->getDeclName()
+        << SourceRange(BuiltinLoc, RParenLoc);
+      Diag(MemberDecl->getLocation(), diag::note_bitfield_decl);
+      return ExprError();
+    }
+      
     if (cast<RecordDecl>(MemberDecl->getDeclContext())->
-        isAnonymousStructOrUnion()) {
+                                                isAnonymousStructOrUnion()) {
       llvm::SmallVector<FieldDecl*, 4> Path;
       BuildAnonymousStructUnionMemberPath(MemberDecl, Path);
       unsigned n = Path.size();
@@ -6854,6 +6864,18 @@
         return ExprError(Diag(BuiltinLoc, diag::err_no_member)
                          << OC.U.IdentInfo << RD << SourceRange(OC.LocStart, OC.LocEnd));
       
+      // C99 7.17p3:
+      //   (If the specified member is a bit-field, the behavior is undefined.)
+      //
+      // We diagnose this as an error.
+      if (MemberDecl->getBitWidth()) {
+        Diag(OC.LocEnd, diag::err_offsetof_bitfield)
+          << MemberDecl->getDeclName()
+          << SourceRange(BuiltinLoc, RPLoc);
+        Diag(MemberDecl->getLocation(), diag::note_bitfield_decl);
+        return ExprError();
+      }
+      
       // FIXME: C++: Verify that MemberDecl isn't a static field.
       // FIXME: Verify that MemberDecl isn't a bitfield.
       if (cast<RecordDecl>(MemberDecl->getDeclContext())->isAnonymousStructOrUnion()) {

Modified: cfe/trunk/test/Sema/offsetof.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/offsetof.c?rev=102548&r1=102547&r2=102548&view=diff
==============================================================================
--- cfe/trunk/test/Sema/offsetof.c (original)
+++ cfe/trunk/test/Sema/offsetof.c Wed Apr 28 17:36:06 2010
@@ -53,4 +53,12 @@
 struct incomplete; // expected-note 2 {{forward declaration of 'struct incomplete'}}
 int test1[__builtin_offsetof(struct incomplete, foo)]; // expected-error {{offsetof of incomplete type 'struct incomplete'}}
 
-int test1[__builtin_offsetof(struct incomplete[10], [4].foo)]; // expected-error {{array has incomplete element type 'struct incomplete'}}
+int test2[__builtin_offsetof(struct incomplete[10], [4].foo)]; // expected-error {{array has incomplete element type 'struct incomplete'}}
+
+// Bitfields
+struct has_bitfields {
+  int i : 7;
+  int j : 12; // expected-note{{bit-field is declared here}}
+};
+
+int test3 = __builtin_offsetof(struct has_bitfields, j); // expected-error{{cannot compute offset of bit-field 'j'}}

Modified: cfe/trunk/test/SemaCXX/offsetof.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/offsetof.cpp?rev=102548&r1=102547&r2=102548&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/offsetof.cpp (original)
+++ cfe/trunk/test/SemaCXX/offsetof.cpp Wed Apr 28 17:36:06 2010
@@ -28,3 +28,11 @@
   int array0[__builtin_offsetof(HasArray, array[5])];
   int array1[__builtin_offsetof(HasArray, array[i])]; // expected-error{{variable length arrays are not permitted in C++}}
 }
+
+// Bitfields
+struct has_bitfields {
+  int i : 7;
+  int j : 12; // expected-note{{bit-field is declared here}}
+};
+
+int test3 = __builtin_offsetof(struct has_bitfields, j); // expected-error{{cannot compute offset of bit-field 'j'}}





More information about the cfe-commits mailing list