[cfe-commits] r55621 - in /cfe/trunk: include/clang/Basic/DiagnosticKinds.def lib/Sema/SemaDeclAttr.cpp test/Sema/transparent-union-pointer.c

Eli Friedman eli.friedman at gmail.com
Mon Sep 1 22:19:24 PDT 2008


Author: efriedma
Date: Tue Sep  2 00:19:23 2008
New Revision: 55621

URL: http://llvm.org/viewvc/llvm-project?rev=55621&view=rev
Log:
An extremely hacky version of transparent_union support; it isn't 
anywhere near correct in terms of missing cases and missing 
diagnostics, but it's good enough to handle the uses in the 
Linux system headers, which are currently a constant pain for compiling 
applications on Linux.


Added:
    cfe/trunk/test/Sema/transparent-union-pointer.c
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=55621&r1=55620&r2=55621&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Tue Sep  2 00:19:23 2008
@@ -694,6 +694,9 @@
      "'%0' attribute invalid on this declaration, requires typedef or value")
 DIAG(warn_attribute_nonnull_no_pointers, WARNING,
   "'nonnull' attribute applied to function with no pointer arguments")
+DIAG(warn_transparent_union_nonpointer, WARNING,
+  "'transparent_union' attribute support incomplete; only supported for"
+  "pointer unions")
   
 // Clang-Specific Attributes
 DIAG(err_attribute_iboutlet_non_ivar, ERROR,

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=55621&r1=55620&r2=55621&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Sep  2 00:19:23 2008
@@ -725,19 +725,34 @@
     return;
   }
 
-  TypeDecl *decl = dyn_cast<TypeDecl>(d);
-
-  if (!decl || !S.Context.getTypeDeclType(decl)->isUnionType()) {
+  // FIXME: This shouldn't be restricted to typedefs
+  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
+  if (!TD || !TD->getUnderlyingType()->isUnionType()) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
          "transparent_union", "union");
     return;
   }
 
-  //QualType QTy = Context.getTypeDeclType(decl);
-  //const RecordType *Ty = QTy->getAsUnionType();
+  RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
+
+  // FIXME: Should we do a check for RD->isDefinition()?
 
-// FIXME
-// Ty->addAttr(new TransparentUnionAttr());
+  // FIXME: This isn't supposed to be restricted to pointers, but otherwise
+  // we might silently generate incorrect code; see following code
+  for (int i = 0; i < RD->getNumMembers(); i++) {
+    if (!RD->getMember(i)->getType()->isPointerType()) {
+      S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer);
+      return;
+    }
+  }
+
+  // FIXME: This is a complete hack; we should be properly propagating
+  // transparent_union through Sema.  That said, this is close enough to
+  // correctly compile all the common cases of transparent_union without
+  // errors or warnings
+  QualType NewTy = S.Context.VoidPtrTy;
+  NewTy.addConst();
+  TD->setUnderlyingType(NewTy);
 }
 
 static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {

Added: cfe/trunk/test/Sema/transparent-union-pointer.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/transparent-union-pointer.c?rev=55621&view=auto

==============================================================================
--- cfe/trunk/test/Sema/transparent-union-pointer.c (added)
+++ cfe/trunk/test/Sema/transparent-union-pointer.c Tue Sep  2 00:19:23 2008
@@ -0,0 +1,14 @@
+// RUN: clang %s -fsyntax-only -verify
+
+typedef union   {
+	union wait *__uptr;
+	int *__iptr;
+} __WAIT_STATUS __attribute__ ((__transparent_union__));
+
+extern int wait (__WAIT_STATUS __stat_loc);
+
+void fastcgi_cleanup() {
+	int status = 0;
+	wait(&status);
+}
+





More information about the cfe-commits mailing list