Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang][NFC] Specify Type and ExtQuals as having 16-byte alignment #68377

Merged
merged 3 commits into from
Oct 12, 2023

Conversation

Endilll
Copy link
Contributor

@Endilll Endilll commented Oct 6, 2023

While working on LLDB visualizer for QualType, I stumbled upon Type and ExtQuals defined with alignas(8). Such alignment leaves only 3 lower bits available for pointer tagging, whereas QualType requires 4 (3 qualifiers + discriminator between Type * and ExtQuals *). Turns out Type and its derived classes are allocated with TypeAlignment == 16 passed to Allocate(). So I'm removing misleading alignas(8) and fixing corresponding static asserts. Since they are already allocated with 16-byte alignment, this is a non-functional change.

@Endilll Endilll added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Oct 6, 2023
@llvmbot llvmbot added the clang Clang issues not falling into any other category label Oct 6, 2023
@llvmbot
Copy link

llvmbot commented Oct 6, 2023

@llvm/pr-subscribers-clang

Changes

While working on LLDB visualizer for QualType, I stumbled upon Type and ExtQuals defined with alignas(8). Such alignment leaves only 3 lower bits available for pointer tagging, whereas QualType requires 4 (3 qualifiers + discriminator between Type * and ExtQuals *). Turns out Type and its derived classes are allocated with TypeAlignment == 16 passed to Allocate(). So I'm removing misleading alignas(8) and fixing corresponding static asserts. Since they are already allocated with 16-byte alignment, this is a non-functional change.


Full diff: https://github.com/llvm/llvm-project/pull/68377.diff

1 Files Affected:

  • (modified) clang/include/clang/AST/Type.h (+10-7)
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index a78d8f60462b231..4e98858f6e9432a 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1482,7 +1482,7 @@ class ExtQualsTypeCommonBase {
 /// in three low bits on the QualType pointer; a fourth bit records whether
 /// the pointer is an ExtQuals node. The extended qualifiers (address spaces,
 /// Objective-C GC attributes) are much more rare.
-class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode {
+class alignas(TypeAlignment) ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode {
   // NOTE: changing the fast qualifiers should be straightforward as
   // long as you don't make 'const' non-fast.
   // 1. Qualifiers:
@@ -1507,6 +1507,9 @@ class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode {
       : ExtQualsTypeCommonBase(baseType,
                                canon.isNull() ? QualType(this_(), 0) : canon),
         Quals(quals) {
+    static_assert(alignof(decltype(*this)) % TypeAlignment == 0,
+                  "Insufficient alignment!");
+
     assert(Quals.hasNonFastQualifiers()
            && "ExtQuals created with no fast qualifiers");
     assert(!Quals.hasFastQualifiers()
@@ -1594,7 +1597,7 @@ enum class AutoTypeKeyword {
 ///
 /// Types, once created, are immutable.
 ///
-class alignas(8) Type : public ExtQualsTypeCommonBase {
+class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
 public:
   enum TypeClass {
 #define TYPE(Class, Base) Class,
@@ -1982,9 +1985,9 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
   Type(TypeClass tc, QualType canon, TypeDependence Dependence)
       : ExtQualsTypeCommonBase(this,
                                canon.isNull() ? QualType(this_(), 0) : canon) {
-    static_assert(sizeof(*this) <= 8 + sizeof(ExtQualsTypeCommonBase),
+    static_assert(sizeof(*this) <= 16 + sizeof(ExtQualsTypeCommonBase),
                   "changing bitfields changed sizeof(Type)!");
-    static_assert(alignof(decltype(*this)) % sizeof(void *) == 0,
+    static_assert(alignof(decltype(*this)) % TypeAlignment == 0,
                   "Insufficient alignment!");
     TypeBits.TC = tc;
     TypeBits.Dependence = static_cast<unsigned>(Dependence);
@@ -5348,7 +5351,7 @@ class DeducedType : public Type {
 
 /// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained
 /// by a type-constraint.
-class alignas(8) AutoType : public DeducedType, public llvm::FoldingSetNode {
+class AutoType : public DeducedType, public llvm::FoldingSetNode {
   friend class ASTContext; // ASTContext creates these
 
   ConceptDecl *TypeConstraintConcept;
@@ -5456,7 +5459,7 @@ class DeducedTemplateSpecializationType : public DeducedType,
 /// TemplateArguments, followed by a QualType representing the
 /// non-canonical aliased type when the template is a type alias
 /// template.
-class alignas(8) TemplateSpecializationType
+class TemplateSpecializationType
     : public Type,
       public llvm::FoldingSetNode {
   friend class ASTContext; // ASTContext creates these
@@ -5872,7 +5875,7 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
 /// Represents a template specialization type whose template cannot be
 /// resolved, e.g.
 ///   A<T>::template B<T>
-class alignas(8) DependentTemplateSpecializationType
+class DependentTemplateSpecializationType
     : public TypeWithKeyword,
       public llvm::FoldingSetNode {
   friend class ASTContext; // ASTContext creates these

@Endilll
Copy link
Contributor Author

Endilll commented Oct 6, 2023

My plan is to phase-out TypeAlignment in subsequent patches, because we have proper language support for alignas and alignof now. It's the only one of its kind passed to Allocate() (I inspected all references to this function).

@Endilll
Copy link
Contributor Author

Endilll commented Oct 6, 2023

CC @zygoloid as the author of ee0ce30

@Endilll Endilll removed the clang Clang issues not falling into any other category label Oct 6, 2023
@github-actions
Copy link

github-actions bot commented Oct 6, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

@llvmbot llvmbot added the clang Clang issues not falling into any other category label Oct 6, 2023
@Endilll Endilll removed the clang Clang issues not falling into any other category label Oct 6, 2023
Copy link
Contributor

@cor3ntin cor3ntin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally LGTM, i just have 1 small concern regarding allowing a bigger Type

clang/include/clang/AST/Type.h Outdated Show resolved Hide resolved
AaronBallman pushed a commit that referenced this pull request Oct 6, 2023
While working on #68377 inspecting `Allocate()` calls, I found out that
there are couple of places where we forget to use placement-new to
create objects in the allocated memory.
@llvmbot llvmbot added the clang Clang issues not falling into any other category label Oct 7, 2023
Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! If @zygoloid (or others) have concerns, we can revert and address them post-commit.

@Endilll Endilll merged commit 4c6cba3 into llvm:main Oct 12, 2023
4 checks passed
@Endilll Endilll deleted the clang_type_alignment branch October 12, 2023 17:54
Endilll added a commit that referenced this pull request Oct 17, 2023
This patch replaces usages of `TypeAlignment` with `alignof(T)`, where `T` is type that will be created in allocated storage with placement-new. This is now possible, because `alignof` reports the correct alignment for `Type` and classes derived from it after #68377 was merged.

While preparing #68377 I verified via `static_assert` that there are no mismatches of alignment between `TypeAlignment` and alignment of types derived from `Type`, so no changes are expected to codegen.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants