[cfe-dev] __declspec(align) with MSVC-built clang

Dean Pavlekovic dpavlekovic at gmail.com
Fri Oct 28 02:06:23 PDT 2011


Hi,

I noticed clang (MSVC built: clang version 3.0 (trunk 143028) Target:
x86_64-pc-win32) seems to ignore __declspec(align(n)) when I was
trying to compile the winpthreads library from mingw-w64 project.

This causes APIs like setjmp(), GetThreadContext() to fail (there are
most likely more but these I have encountered and can confirm to work
after fixing).

I first tried some macro "massage" that replaced __declspec(align(n))
with __attribute__((aligned(n)) and things compiled and worked fine.
Such workaround is not elegant I think: it feels a bit dangerous to
#define align(x) aligned(x) #define __declspec(x) __attribute__((x))
globally? How would this affect other supported __declspecs
(dllimport, dllexport...)?

Since this didn't seem too complicated I wondered if I could make my
first clang "hack" ;) It turned out there's not more to do than:

Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp   (revision 143028)
+++ lib/Sema/SemaDeclAttr.cpp   (working copy)
@@ -3415,7 +3415,8 @@
 static bool isKnownDeclSpecAttr(const AttributeList &Attr) {
   return Attr.getKind() == AttributeList::AT_dllimport ||
          Attr.getKind() == AttributeList::AT_dllexport ||
-         Attr.getKind() == AttributeList::AT_uuid;
+         Attr.getKind() == AttributeList::AT_uuid ||
+         Attr.getKind() == AttributeList::AT_aligned;
 }

"align" already is handled same as "aligned" in
AttributeList::getKind() both returning AT_aligned and looks like the
only thing preventing __declspec(align()) to be ignored is this piece
in SemaDeclAttr.cpp:3718:
static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
                                 const AttributeList &Attr,
                                 bool NonInheritable, bool Inheritable) {
  if (Attr.isInvalid())
    return;

>>>  if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
    // FIXME: Try to deal with other __declspec attributes!
    return;

   ...

Now... is this too simple to be correct? For me it solved misalignment
problems in winpthreads but I'm not aware if it could cause problems
elswehere?

---

One other thing: apparently MSVC *ignores*__stdcall function attribute
when compiling for x64. From
http://msdn.microsoft.com/en-us/library/zxk0tw93(v=VS.100).aspx :
"""On Itanium Processor Family (IPF) and x64 processors, __stdcall is
accepted and ignored by the compiler; on IPF, by convention,
parameters are passed in register."""
clang doesn't ignore it and __stdcall-style symbol names are emitted
to objects which causes link errors. But this is easily worked around
by defining __stdcall to empty.

Cheers,
Dean



More information about the cfe-dev mailing list