Recommited:

Fix for PR16752. Second commit.

PR16752: 'mode' attribute for unusual targets doesn't work properly
Description:
Troubles could be happened due to some assumptions in handleModeAttr function (see SemaDeclAttr.cpp).
For example, it assumes that 32 bit integer is 'int', while it could be 16 bit only.
Instead of asking target: 'which type do you want to use for int32_t ?' it just hardcodes general opinion. That doesn't looks pretty correct.
Please consider the next solution:
1. In Basic/TargetInfo add getIntTypeByWidth and getRealTypeByWidth methods. Methods asks target for proper type for given bit width.
2. Fix handleModeAttr according to new methods in TargetInfo.

Fixes:
1st Commit (Done): Add new methods for TargetInfo:
     getRealTypeByWidth and getIntTypeByWidth
  for ASTContext names are almost same(invokes new methods from TargetInfo):
     getIntTypeForBitwidth and getRealTypeForBitwidth

2nd Commit (Current): Fix SemaDeclAttr, handleModeAttr function.

Also test/Sema/attr-mode.c was fixed. 'XC' mode test was disabled for PPC64 machines.

llvm-svn: 190926
This commit is contained in:
Stepan Dyatkovskiy 2013-09-18 09:08:52 +00:00
parent 718ce62b3c
commit b88c30facd
2 changed files with 15 additions and 65 deletions

View File

@ -3460,77 +3460,24 @@ static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
// and friends, at least with glibc.
// FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
// width on unusual platforms.
// FIXME: Make sure floating-point mappings are accurate
// FIXME: Support XF and TF types
QualType NewTy;
switch (DestWidth) {
case 0:
if (!DestWidth) {
S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
return;
default:
}
QualType NewTy;
if (IntegerMode)
NewTy = S.Context.getIntTypeForBitwidth(DestWidth,
OldTy->isSignedIntegerType());
else
NewTy = S.Context.getRealTypeForBitwidth(DestWidth);
if (NewTy.isNull()) {
S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
return;
case 8:
if (!IntegerMode) {
S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
return;
}
if (OldTy->isSignedIntegerType())
NewTy = S.Context.SignedCharTy;
else
NewTy = S.Context.UnsignedCharTy;
break;
case 16:
if (!IntegerMode) {
S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
return;
}
if (OldTy->isSignedIntegerType())
NewTy = S.Context.ShortTy;
else
NewTy = S.Context.UnsignedShortTy;
break;
case 32:
if (!IntegerMode)
NewTy = S.Context.FloatTy;
else if (OldTy->isSignedIntegerType())
NewTy = S.Context.IntTy;
else
NewTy = S.Context.UnsignedIntTy;
break;
case 64:
if (!IntegerMode)
NewTy = S.Context.DoubleTy;
else if (OldTy->isSignedIntegerType())
if (S.Context.getTargetInfo().getLongWidth() == 64)
NewTy = S.Context.LongTy;
else
NewTy = S.Context.LongLongTy;
else
if (S.Context.getTargetInfo().getLongWidth() == 64)
NewTy = S.Context.UnsignedLongTy;
else
NewTy = S.Context.UnsignedLongLongTy;
break;
case 96:
NewTy = S.Context.LongDoubleTy;
break;
case 128:
if (!IntegerMode && &S.Context.getTargetInfo().getLongDoubleFormat() !=
&llvm::APFloat::PPCDoubleDouble) {
S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
return;
}
if (IntegerMode) {
if (OldTy->isSignedIntegerType())
NewTy = S.Context.Int128Ty;
else
NewTy = S.Context.UnsignedInt128Ty;
} else
NewTy = S.Context.LongDoubleTy;
break;
}
if (ComplexMode) {

View File

@ -27,7 +27,10 @@ int **__attribute((mode(QI)))* i32; // expected-error{{mode attribute}}
typedef _Complex double c32 __attribute((mode(SC)));
int c32_test[sizeof(c32) == 8 ? 1 : -1];
typedef _Complex float c64 __attribute((mode(DC)));
#ifndef TEST_64BIT_PPC64 // Note, 'XC' mode is illegal for PPC64 machines.
typedef _Complex float c80 __attribute((mode(XC)));
#endif
// PR6108: Correctly select 'long' built in type on 64-bit platforms for 64 bit
// modes. Also test other mode-based conversions.