OSDN Git Service

[Sema] Introduce MaximumAlignment value, to be used instead of magical constants
authorRoman Lebedev <lebedev.ri@gmail.com>
Fri, 24 Jan 2020 14:01:27 +0000 (17:01 +0300)
committerRoman Lebedev <lebedev.ri@gmail.com>
Fri, 24 Jan 2020 14:49:17 +0000 (17:49 +0300)
There is llvm::Value::MaximumAlignment, which is numerically
equivalent to these constants, but we can't use it directly
because we can't include llvm IR headers in clang Sema.
So instead, copy-paste the constant, and fixup the places to use it.

This was initially reviewed in https://reviews.llvm.org/D72998

clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaChecking.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/CXX/drs/dr6xx.cpp
clang/test/Sema/attr-aligned.c

index fae1ade..92d964d 100644 (file)
@@ -372,6 +372,15 @@ class Sema final {
                                       QualType ResultTy,
                                       ArrayRef<QualType> Args);
 
+  /// The maximum alignment, same as in llvm::Value. We duplicate them here
+  /// because that allows us not to duplicate the constants in clang code,
+  /// which we must to since we can't directly use the llvm constants.
+  ///
+  /// This is the greatest alignment value supported by load, store, and alloca
+  /// instructions, and global values.
+  static const unsigned MaxAlignmentExponent = 29;
+  static const unsigned MaximumAlignment = 1u << MaxAlignmentExponent;
+
 public:
   typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
   typedef OpaquePtr<TemplateName> TemplateTy;
index 4485539..186f2b5 100644 (file)
@@ -3665,11 +3665,9 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
           return;
         }
 
-        // Alignment calculations can wrap around if it's greater than 2**29.
-        unsigned MaximumAlignment = 536870912;
-        if (I > MaximumAlignment)
+        if (I > Sema::MaximumAlignment)
           Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
-              << Arg->getSourceRange() << MaximumAlignment;
+              << Arg->getSourceRange() << Sema::MaximumAlignment;
       }
     }
   }
@@ -5394,11 +5392,9 @@ bool Sema::SemaBuiltinAssumeAligned(CallExpr *TheCall) {
       return Diag(TheCall->getBeginLoc(), diag::err_alignment_not_power_of_two)
              << Arg->getSourceRange();
 
-    // Alignment calculations can wrap around if it's greater than 2**29.
-    unsigned MaximumAlignment = 536870912;
-    if (Result > MaximumAlignment)
+    if (Result > Sema::MaximumAlignment)
       Diag(TheCall->getBeginLoc(), diag::warn_assume_aligned_too_great)
-          << Arg->getSourceRange() << MaximumAlignment;
+          << Arg->getSourceRange() << Sema::MaximumAlignment;
   }
 
   if (NumArgs > 2) {
index 8ad981f..e097ec0 100644 (file)
@@ -1626,11 +1626,9 @@ void Sema::AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
       return;
     }
 
-    // Alignment calculations can wrap around if it's greater than 2**29.
-    unsigned MaximumAlignment = 536870912;
-    if (I > MaximumAlignment)
+    if (I > Sema::MaximumAlignment)
       Diag(CI.getLoc(), diag::warn_assume_aligned_too_great)
-          << CI.getRange() << MaximumAlignment;
+          << CI.getRange() << Sema::MaximumAlignment;
   }
 
   if (OE) {
@@ -3816,13 +3814,12 @@ void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
     }
   }
 
-  // Alignment calculations can wrap around if it's greater than 2**28.
-  unsigned MaxValidAlignment =
-      Context.getTargetInfo().getTriple().isOSBinFormatCOFF() ? 8192
-                                                              : 268435456;
-  if (AlignVal > MaxValidAlignment) {
+  unsigned MaximumAlignment = Sema::MaximumAlignment;
+  if (Context.getTargetInfo().getTriple().isOSBinFormatCOFF())
+    MaximumAlignment = std::min(MaximumAlignment, 8192u);
+  if (AlignVal > MaximumAlignment) {
     Diag(AttrLoc, diag::err_attribute_aligned_too_great)
-        << MaxValidAlignment << E->getSourceRange();
+        << MaximumAlignment << E->getSourceRange();
     return;
   }
 
index 6ff1625..7a0adb5 100644 (file)
@@ -551,9 +551,9 @@ namespace dr648 { // dr648: yes
 
 #if __cplusplus >= 201103L
 namespace dr649 { // dr649: yes
-  alignas(0x20000000) int n; // expected-error {{requested alignment}}
-  struct alignas(0x20000000) X {}; // expected-error {{requested alignment}}
-  struct Y { int n alignas(0x20000000); }; // expected-error {{requested alignment}}
+  alignas(0x40000000) int n; // expected-error {{requested alignment}}1
+  struct alignas(0x40000000) X {}; // expected-error {{requested alignment}}
+  struct Y { int n alignas(0x40000000); }; // expected-error {{requested alignment}}
   struct alignas(256) Z {};
   // This part is superseded by dr2130 and eventually by aligned allocation support.
   auto *p = new Z;
index b8d2fc6..1d65ef4 100644 (file)
@@ -1,14 +1,15 @@
 // RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
 
 int x __attribute__((aligned(3))); // expected-error {{requested alignment is not a power of 2}}
-int y __attribute__((aligned(1 << 29))); // expected-error {{requested alignment must be 268435456 bytes or smaller}}
+int y __attribute__((aligned(1 << 30))); // expected-error {{requested alignment must be 536870912 bytes or smaller}}
 
 // PR26444
+int y __attribute__((aligned(1 << 29)));
 int y __attribute__((aligned(1 << 28)));
 
 // PR3254
 short g0[3] __attribute__((aligned));
-short g0_chk[__alignof__(g0) == 16 ? 1 : -1]; 
+short g0_chk[__alignof__(g0) == 16 ? 1 : -1];
 
 // <rdar://problem/6840045>
 typedef char ueber_aligned_char __attribute__((aligned(8)));