r187999 - Fix alignof computation of large arrays on x86_64.

Rafael Espindola rafael.espindola at gmail.com
Thu Aug 8 12:53:46 PDT 2013


Author: rafael
Date: Thu Aug  8 14:53:46 2013
New Revision: 187999

URL: http://llvm.org/viewvc/llvm-project?rev=187999&view=rev
Log:
Fix alignof computation of large arrays on x86_64.

We were exposing the extra alignment given to large arrays. The new behavior
matches gcc, which is a good thing since this is a gcc extension.

Thanks to Joerg Sonnenberger for noticing it.

While at it, centralize the method description in the .h file.

Added:
    cfe/trunk/test/CodeGen/align-x68_64.c
Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/test/Sema/align-x86-64.c
    cfe/trunk/test/SemaCXX/alignof.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=187999&r1=187998&r2=187999&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Aug  8 14:53:46 2013
@@ -1622,9 +1622,11 @@ public:
   /// \pre \p D must not be a bitfield type, as bitfields do not have a valid
   /// alignment.
   ///
-  /// If \p RefAsPointee, references are treated like their underlying type
-  /// (for alignof), else they're treated like pointers (for CodeGen).
-  CharUnits getDeclAlign(const Decl *D, bool RefAsPointee = false) const;
+  /// If \p ForAlignof, references are treated like their underlying type
+  /// and  large arrays don't get any special treatment. If not \p ForAlignof
+  /// it computes the value expected by CodeGen: references are treated like
+  /// pointers and large arrays get extra alignment.
+  CharUnits getDeclAlign(const Decl *D, bool ForAlignof = false) const;
 
   /// \brief Get or compute information about the layout of the specified
   /// record (struct/union/class) \p D, which indicates its size and field

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=187999&r1=187998&r2=187999&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Aug  8 14:53:46 2013
@@ -1239,12 +1239,7 @@ const llvm::fltSemantics &ASTContext::ge
   }
 }
 
-/// getDeclAlign - Return a conservative estimate of the alignment of the
-/// specified decl.  Note that bitfields do not have a valid alignment, so
-/// this method will assert on them.
-/// If @p RefAsPointee, references are treated like their underlying type
-/// (for alignof), else they're treated like pointers (for CodeGen).
-CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) const {
+CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
   unsigned Align = Target->getCharWidth();
 
   bool UseAlignAttrOnly = false;
@@ -1277,7 +1272,7 @@ 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 (RefAsPointee)
+      if (ForAlignof)
         T = RT->getPointeeType();
       else
         T = getPointerType(RT->getPointeeType());
@@ -1285,9 +1280,9 @@ CharUnits ASTContext::getDeclAlign(const
     if (!T->isIncompleteType() && !T->isFunctionType()) {
       // Adjust alignments of declarations with array type by the
       // large-array alignment on the target.
-      unsigned MinWidth = Target->getLargeArrayMinWidth();
       if (const ArrayType *arrayType = getAsArrayType(T)) {
-        if (MinWidth) {
+        unsigned MinWidth = Target->getLargeArrayMinWidth();
+        if (!ForAlignof && MinWidth) {
           if (isa<VariableArrayType>(arrayType))
             Align = std::max(Align, Target->getLargeArrayAlign());
           else if (isa<ConstantArrayType>(arrayType) &&

Added: cfe/trunk/test/CodeGen/align-x68_64.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/align-x68_64.c?rev=187999&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/align-x68_64.c (added)
+++ cfe/trunk/test/CodeGen/align-x68_64.c Thu Aug  8 14:53:46 2013
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// PR5599
+
+void test1_f(void *);
+
+void test1_g(void) {
+  float x[4];
+  test1_f(x);
+}
+// CHECK: @test1_g
+// CHECK: alloca [4 x float], align 16

Modified: cfe/trunk/test/Sema/align-x86-64.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/align-x86-64.c?rev=187999&r1=187998&r2=187999&view=diff
==============================================================================
--- cfe/trunk/test/Sema/align-x86-64.c (original)
+++ cfe/trunk/test/Sema/align-x86-64.c Thu Aug  8 14:53:46 2013
@@ -1,16 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify %s
 // expected-no-diagnostics
 
-// PR5599
-
-void frob(void *);
-
-void foo(void) {
-  float x[4];
-  char y[__alignof__(x) == 16 ? 1 : -1];
-  frob(y);
-}
-
 // PR5637
 
 typedef __attribute__((aligned(16))) struct {

Modified: cfe/trunk/test/SemaCXX/alignof.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/alignof.cpp?rev=187999&r1=187998&r2=187999&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/alignof.cpp (original)
+++ cfe/trunk/test/SemaCXX/alignof.cpp Thu Aug  8 14:53:46 2013
@@ -58,3 +58,7 @@ struct S5 {
   int x;
 };
 const int test8 = __alignof__(S5::x);
+
+long long int test14[2];
+
+static_assert(alignof(test14) == 8, "foo"); // expected-warning {{'alignof' applied to an expression is a GNU extension}}





More information about the cfe-commits mailing list