r210608 - Related to PR19992: when the GNU alignof-expression extension is applied to an
Richard Smith
richard-llvm at metafoo.co.uk
Tue Jun 10 16:34:28 PDT 2014
Author: rsmith
Date: Tue Jun 10 18:34:28 2014
New Revision: 210608
URL: http://llvm.org/viewvc/llvm-project?rev=210608&view=rev
Log:
Related to PR19992: when the GNU alignof-expression extension is applied to an
expression of array-of-unknown-bound type, don't try to complete the array
bound, and return the alignment of the element type rather than 1.
Modified:
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/SemaCXX/alignof.cpp
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=210608&r1=210607&r2=210608&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Jun 10 18:34:28 2014
@@ -1309,13 +1309,14 @@ CharUnits ASTContext::getDeclAlign(const
} else if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
QualType T = VD->getType();
- if (const ReferenceType* RT = T->getAs<ReferenceType>()) {
+ if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
if (ForAlignof)
T = RT->getPointeeType();
else
T = getPointerType(RT->getPointeeType());
}
- if (!T->isIncompleteType() && !T->isFunctionType()) {
+ QualType BaseT = getBaseElementType(T);
+ if (!BaseT->isIncompleteType() && !T->isFunctionType()) {
// Adjust alignments of declarations with array type by the
// large-array alignment on the target.
if (const ArrayType *arrayType = getAsArrayType(T)) {
@@ -1330,8 +1331,12 @@ CharUnits ASTContext::getDeclAlign(const
// Keep track of extra alignment requirements on the array itself, then
// work with the element type.
+ //
+ // FIXME: Computing the preferred type alignment for the array element
+ // type should not be necessary, but getPreferredTypeAlign returns the
+ // wrong thing in some cases (such as 'long long[]' on x86_64).
Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
- T = getBaseElementType(arrayType);
+ T = BaseT;
}
Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=210608&r1=210607&r2=210608&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Jun 10 18:34:28 2014
@@ -6910,8 +6910,9 @@ bool IntExprEvaluator::VisitBinaryOperat
}
CharUnits IntExprEvaluator::GetAlignOfType(QualType T) {
- // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
- // result shall be the alignment of the referenced type."
+ // C++ [expr.alignof]p3:
+ // When alignof is applied to a reference type, the result is the
+ // alignment of the referenced type.
if (const ReferenceType *Ref = T->getAs<ReferenceType>())
T = Ref->getPointeeType();
@@ -6930,7 +6931,7 @@ CharUnits IntExprEvaluator::GetAlignOfEx
// alignof decl is always accepted, even if it doesn't make sense: we default
// to 1 in those cases.
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
- return Info.Ctx.getDeclAlign(DRE->getDecl(),
+ return Info.Ctx.getDeclAlign(DRE->getDecl(),
/*RefAsPointee*/true);
if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=210608&r1=210607&r2=210608&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jun 10 18:34:28 2014
@@ -3341,10 +3341,21 @@ bool Sema::CheckUnaryExprOrTypeTraitOper
E->getSourceRange(), ExprKind))
return false;
- if (RequireCompleteExprType(E,
- diag::err_sizeof_alignof_incomplete_type,
- ExprKind, E->getSourceRange()))
- return true;
+ // 'alignof' applied to an expression only requires the base element type of
+ // the expression to be complete. 'sizeof' requires the expression's type to
+ // be complete (and will attempt to complete it if it's an array of unknown
+ // bound).
+ if (ExprKind == UETT_AlignOf) {
+ if (RequireCompleteType(E->getExprLoc(),
+ Context.getBaseElementType(E->getType()),
+ diag::err_sizeof_alignof_incomplete_type, ExprKind,
+ E->getSourceRange()))
+ return true;
+ } else {
+ if (RequireCompleteExprType(E, diag::err_sizeof_alignof_incomplete_type,
+ ExprKind, E->getSourceRange()))
+ return true;
+ }
// Completing the expression's type may have changed it.
ExprTy = E->getType();
Modified: cfe/trunk/test/SemaCXX/alignof.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/alignof.cpp?rev=210608&r1=210607&r2=210608&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/alignof.cpp (original)
+++ cfe/trunk/test/SemaCXX/alignof.cpp Tue Jun 10 18:34:28 2014
@@ -64,7 +64,16 @@ long long int test14[2];
static_assert(alignof(test14) == 8, "foo"); // expected-warning {{'alignof' applied to an expression is a GNU extension}}
// PR19992
-alignas(32) extern int test15[];
static_assert(alignof(int[]) == alignof(int), ""); // ok
-// FIXME: We should accept this.
-static_assert(alignof(test15) == 32, ""); // expected-warning {{GNU extension}} expected-error {{incomplete type}}
+
+namespace alignof_array_expr {
+ alignas(32) extern int n[];
+ static_assert(alignof(n) == 32, ""); // expected-warning {{GNU extension}}
+
+ template<int> struct S {
+ static int a[];
+ };
+ template<int N> int S<N>::a[N];
+ // ok, does not complete type of S<-1>::a
+ static_assert(alignof(S<-1>::a) == alignof(int), ""); // expected-warning {{GNU extension}}
+}
More information about the cfe-commits
mailing list