diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index c1bbc5f085..c72c239320 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1670,8 +1670,16 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { break; } - if (const EnumType *ET = dyn_cast(TT)) - return getTypeInfo(ET->getDecl()->getIntegerType()); + if (const EnumType *ET = dyn_cast(TT)) { + const EnumDecl *ED = ET->getDecl(); + TypeInfo Info = + getTypeInfo(ED->getIntegerType()->getUnqualifiedDesugaredType()); + if (unsigned AttrAlign = ED->getMaxAlignment()) { + Info.Align = AttrAlign; + Info.AlignIsRequired = true; + } + return Info; + } const RecordType *RT = cast(TT); const ASTRecordLayout &Layout = getASTRecordLayout(RT->getDecl()); @@ -1786,6 +1794,8 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const { T = T->getBaseElementTypeUnsafe(); if (const ComplexType *CT = T->getAs()) T = CT->getElementType().getTypePtr(); + if (const EnumType *ET = T->getAs()) + T = ET->getDecl()->getIntegerType().getTypePtr(); if (T->isSpecificBuiltinType(BuiltinType::Double) || T->isSpecificBuiltinType(BuiltinType::LongLong) || T->isSpecificBuiltinType(BuiltinType::ULongLong)) diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index c17451eaaa..c083e9ed6c 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -2953,12 +2953,15 @@ void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS, void Sema::CheckAlignasUnderalignment(Decl *D) { assert(D->hasAttrs() && "no attributes on decl"); - QualType Ty; - if (ValueDecl *VD = dyn_cast(D)) - Ty = VD->getType(); - else - Ty = Context.getTagDeclType(cast(D)); - if (Ty->isDependentType() || Ty->isIncompleteType()) + QualType UnderlyingTy, DiagTy; + if (ValueDecl *VD = dyn_cast(D)) { + UnderlyingTy = DiagTy = VD->getType(); + } else { + UnderlyingTy = DiagTy = Context.getTagDeclType(cast(D)); + if (EnumDecl *ED = dyn_cast(D)) + UnderlyingTy = ED->getIntegerType(); + } + if (DiagTy->isDependentType() || DiagTy->isIncompleteType()) return; // C++11 [dcl.align]p5, C11 6.7.5/4: @@ -2977,10 +2980,10 @@ void Sema::CheckAlignasUnderalignment(Decl *D) { if (AlignasAttr && Align) { CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align); - CharUnits NaturalAlign = Context.getTypeAlignInChars(Ty); + CharUnits NaturalAlign = Context.getTypeAlignInChars(UnderlyingTy); if (NaturalAlign > RequestedAlign) Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned) - << Ty << (unsigned)NaturalAlign.getQuantity(); + << DiagTy << (unsigned)NaturalAlign.getQuantity(); } } diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp index 3c250f9d25..e713d72dc5 100644 --- a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp +++ b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp @@ -15,6 +15,12 @@ enum alignas(1) E1 {}; // expected-error {{requested alignment is less than mini enum alignas(1) E2 : char {}; // ok enum alignas(4) E3 { e3 = 0 }; // ok enum alignas(4) E4 { e4 = 1ull << 33 }; // expected-error {{requested alignment is less than minimum alignment of 8 for type 'E4'}} +enum alignas(8) E5 {}; +static_assert(alignof(E5) == 8, ""); + +typedef __attribute__((aligned(16))) int IntAlign16; +enum E6 : IntAlign16 {}; +static_assert(alignof(E6) == 4, ""); struct S1 { alignas(8) int n; diff --git a/test/Sema/align-x86.c b/test/Sema/align-x86.c index f112c6398c..e3b8c704b8 100644 --- a/test/Sema/align-x86.c +++ b/test/Sema/align-x86.c @@ -27,6 +27,8 @@ double g6[3]; short chk1[__alignof__(g6) == 8 ? 1 : -1]; short chk2[__alignof__(double[3]) == 8 ? 1 : -1]; +enum { x = 18446744073709551615ULL } g7; +short chk1[__alignof__(g7) == 8 ? 1 : -1]; // PR5637