This is an archive of the discontinued LLVM Phabricator instance.

PR27132: Proper mangling for __unaligned qualifier (now with PR27367 fixed)
ClosedPublic

Authored by andreybokhanko on Apr 28 2016, 5:09 AM.

Details

Summary

This is exactly same patch as http://reviews.llvm.org/D18596 (already reviewed and LGTMed by rnk), with a couple of changes to fix PR27367:

  • A check for void pointer added to include/clang/AST/Type.h
  • A check for void pointer added to lib/Sema/SemaOverload.cpp
  • A test (from PR27367) added to test/SemaCXX/MicrosoftExtensions.cpp

Yours,

Andrey

Software Engineer
Intel Compiler Team

Diff Detail

Event Timeline

andreybokhanko retitled this revision from to PR27132: Proper mangling for __unaligned qualifier (now with PR27367 fixed).
andreybokhanko updated this object.
andreybokhanko added reviewers: rnk, thakis, majnemer.
andreybokhanko added a subscriber: cfe-commits.
majnemer added inline comments.Apr 28 2016, 10:00 AM
lib/AST/MicrosoftMangle.cpp
1446–1451

Have you tested __restrict with __unaligned on MSVC? I don't see a test for it here.

1583–1585

It would be good to see what MSVC does with:

template <typename T>
T f(T t) { return t; }

Where T is instantiated with int * and int __unaligned *.

lib/Sema/SemaType.cpp
1787

This would probably be easier to read if written as:

unsigned CVR = CVRAU & ~(DeclSpec::TQ_atomic | DeclSpec::TQ_unaligned);
majnemer edited edge metadata.Apr 28 2016, 9:16 PM

It would be good to have a test for the variable template case:

template <typename T>
T x;

auto g() { return x<int __unaligned *>; }

should mangle to ??$x@PEFAH@@3PEFAHEFA

andreybokhanko edited edge metadata.

Fixed a bug uncovered by David Majnemer's review; added tests he asked for.

andreybokhanko marked 3 inline comments as done.Apr 29 2016, 5:40 AM

David, thank you for the review!

It would be good to have a test for the variable template case:

template <typename T>
T x;

auto g() { return x<int __unaligned *>; }

should mangle to ??$x@PEFAH@@3PEFAHEFA

It mangles exaclty to ??$x@PEFAH@@3PEFAHEFA (in 64 bit mode). Test added.

lib/AST/MicrosoftMangle.cpp
1446–1451

Good catch!

Indeed, restrict and unaligned are mangled in a different order. Fixed; test added.

1583–1585

Done. Test added.

majnemer added inline comments.Apr 30 2016, 3:03 AM
lib/AST/MicrosoftMangle.cpp
1583–1584

Hmm, can you give a concrete example why we need this line?

andreybokhanko marked 3 inline comments as done.May 4 2016, 3:32 AM
andreybokhanko added inline comments.
lib/AST/MicrosoftMangle.cpp
1583–1584

Sure. An example is:

__unaligned int unaligned_foo3() { return 0; }

MS mangles it as

?unaligned_foo3@@YAHXZ

However, if __unaligned is taken into account, "if ((!IsPointer && Quals) || isa<TagType>(T))" computes to true and clang adds "?A", resulting to

?unaligned_foo3@@YA?AHXZ

Yours,
Andrey

majnemer added inline comments.May 4 2016, 3:42 PM
lib/AST/MicrosoftMangle.cpp
1583–1584

Wait, I thought __unaligned can only apply to pointer types. Is this not so?!
Does __unaligned int x; really keep it's __unaligned qualifier?

rnk added inline comments.May 4 2016, 3:48 PM
lib/AST/MicrosoftMangle.cpp
1583–1584

Yeah it does:

$ cat t.cpp
__unaligned int x;
$ cl -nologo -c t.cpp && dumpbin /symbols t.obj  | grep ?x
t.cpp
008 00000000 SECT3  notype       External     | ?x@@3HFA (int __unaligned x)
majnemer added inline comments.May 4 2016, 5:21 PM
lib/AST/MicrosoftMangle.cpp
1583–1584

Woah. So if you do:

__unaligned int unaligned_foo3() { return 0; }
auto z = foo3();

How is z mangled?

majnemer added inline comments.May 4 2016, 7:51 PM
lib/AST/MicrosoftMangle.cpp
1583–1584

z is mangled without the qualifiers. In fact:

__unaligned int unaligned_foo3() { return 0; }
__unaligned int z;
auto z = unaligned_foo3();

Is an error:

x.cpp(3): error C2373: 'z': redefinition; different type modifiers
x.cpp(2): note: see declaration of 'z'

Do we have comparable behavior?

andreybokhanko marked an inline comment as done.May 5 2016, 3:25 AM
andreybokhanko added inline comments.
lib/AST/MicrosoftMangle.cpp
1583–1584

Not exactly the same, but comparable, indeed:

$ clang -cc1 ~/test.cpp -std=c++11 -triple i686-pc-win32 -fms-extensions
/nfs/ims/home/asbokhan/test.cpp:3:6: error: redefinition of 'z'
auto z = unaligned_foo3();
     ^
/nfs/ims/home/asbokhan/test.cpp:2:17: note: previous definition is here
__unaligned int z;
                ^
1 error generated.

This has nothing to do with unaligned, though, as both MS compiler and us don't allow redefinitions. If a redefinition has a different unaligned modifier, MS also notes this (with "; different type modifiers" suffix in the message), but it doesn't serve any practical purpose, as changing modifier won't make the code compilable.

Yours,
Andrey

David, just noticed that your first question doesn't have a redefinition. For this program:

__unaligned int unaligned_foo3() { return 0; }
auto z = unaligned_foo3();

Both MS and us mangle z the same:

?z@@3HA

Yours,
Andrey

majnemer accepted this revision.May 5 2016, 8:53 AM
majnemer edited edge metadata.

LGTM

FYI, we will also want to update getAddrOfCXXCatchHandler and getThrowInfo to correctly handle __unaligned.

This revision is now accepted and ready to land.May 5 2016, 8:53 AM
This revision was automatically updated to reflect the committed changes.

David, thank you for the thorough review! -- it definitely made the patch stronger and me even more paranoid than the rest of Intel. :-)

FYI, we will also want to update getAddrOfCXXCatchHandler and getThrowInfo to correctly handle __unaligned.

Do you want me to implement this (I have no idea how EH works on Windows, but can try...) or plan to implement yourself?

Yours,
Andrey

David, thank you for the thorough review! -- it definitely made the patch stronger and me even more paranoid than the rest of Intel. :-)

Thanks for implementing this :)

FYI, we will also want to update getAddrOfCXXCatchHandler and getThrowInfo to correctly handle __unaligned.

Do you want me to implement this (I have no idea how EH works on Windows, but can try...) or plan to implement yourself?

I have no plans to implement this but I don't think it is very difficult. The way I'd go about this is to see what happens when the following occur:

throw (int *__unaligned)nullptr;

MSVC should emit a ThrowInfo object, _TI... which points to a CatchableTypeArray, _CTA... which will point to two CatchableTypes, _CT...: one for pointer-to-void and the other for pointer-to-int.
Both of the CatchableTypes have a bitfield containing qualifiers, among other things. One of these are where __unaligned should go, see getThrowInfo for more details.

Yours,
Andrey