durin42 updated this revision to Diff 415226.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D121629/new/

https://reviews.llvm.org/D121629

Files:
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp

Index: clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp
===================================================================
--- clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp
+++ clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp
@@ -8,15 +8,38 @@
 
 char **__attribute__((alloc_align(2)))
 passthrough(char **x, unsigned long alignment) {
-  // CHECK:      define{{.*}} i8** @[[PASSTHROUGH:.*]](i8** noundef %[[X:.*]], i64 noundef %[[ALIGNMENT:.*]])
-  // CHECK-NEXT: entry:
-  // CHECK-NEXT:   %[[X_ADDR:.*]] = alloca i8**, align 8
-  // CHECK-NEXT:   %[[ALIGNMENT_ADDR:.*]] = alloca i64, align 8
-  // CHECK-NEXT:   store i8** %[[X]], i8*** %[[X_ADDR]], align 8
-  // CHECK-NEXT:   store i64 %[[ALIGNMENT]], i64* %[[ALIGNMENT_ADDR]], align 8
-  // CHECK-NEXT:   %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8
-  // CHECK-NEXT:   ret i8** %[[X_RELOADED]]
-  // CHECK-NEXT: }
+  // CHECK:                            define{{.*}} i8** @[[PASSTHROUGH:.*]](i8** noundef %[[X:.*]], i64 noundef %[[ALIGNMENT:.*]])
+  // CHECK-NEXT:                       entry:
+  // CHECK-SANITIZE-NEXT:                %return.sloc.ptr = alloca i8*, align 8
+  // CHECK-NEXT:                         %[[X_ADDR:.*]] = alloca i8**, align 8
+  // CHECK-NEXT:                         %[[ALIGNMENT_ADDR:.*]] = alloca i64, align 8
+  // CHECK-SANITIZE-NEXT:                store i8* null, i8** %return.sloc.ptr, align 8
+  // CHECK-NEXT:                         store i8** %[[X]], i8*** %[[X_ADDR]], align 8
+  // CHECK-NEXT:                         store i64 %[[ALIGNMENT]], i64* %[[ALIGNMENT_ADDR]], align 8
+  // CHECK-SANITIZE-NEXT:                store i8* bitcast ({ [151 x i8]*, i32, i32 }* @0 to i8*), i8** %return.sloc.ptr, align 8
+  // CHECK-NEXT:                         %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8
+  // CHECK-SANITIZE-NEXT:                %ptrint = ptrtoint i8** %0 to i64
+  // CHECK-SANITIZE-NEXT:                %1 = sub i64 %alignment, 1
+  // CHECK-SANITIZE-NEXT:                %maskedptr = and i64 %ptrint, %1
+  // CHECK-SANITIZE-NEXT:                %maskcond = icmp eq i64 %maskedptr, 0
+  // CHECK-SANITIZE-NEXT:                %2 = ptrtoint i8** %0 to i64, !nosanitize !2
+  // CHECK-SANITIZE-ANYRECOVER-NEXT:     br i1 %maskcond, label %cont, label %handler.alignment_assumption, !prof !3, !nosanitize !2
+  // CHECK-SANITIZE-TRAP-NEXT:           br i1 %maskcond, label %cont, label %trap, !nosanitize !2
+
+  // CHECK-SANITIZE-ANYRECOVER:        handler.alignment_assumption:
+  // CHECK-SANITIZE-NORECOVER-NEXT:      call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ { [151 x i8]*, i32, i32 }, { [151 x i8]*, i32, i32 }, { i16, i16, [10 x i8] }* }* @2 to i8*), i64 %2, i64 %alignment, i64 0) #3, !nosanitize !2
+  // CHECK-SANITIZE-NORECOVER-NEXT:      unreachable, !nosanitize !2
+  // CHECK-SANITIZE-RECOVER-NEXT:        call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ { [151 x i8]*, i32, i32 }, { [151 x i8]*, i32, i32 }, { i16, i16, [10 x i8] }* }* @2 to i8*), i64 %2, i64 %alignment, i64 0) #3, !nosanitize !2
+  // CHECK-SANITIZE-RECOVER-NEXT:        br label %cont, !nosanitize !2
+
+  // CHECK-SANITIZE-TRAP:              trap:
+  // CHECK-SANITIZE-TRAP-NEXT:           call void @llvm.ubsantrap(i8 23) #3, !nosanitize !2
+  // CHECK-SANITIZE-TRAP-NEXT:           unreachable, !nosanitize !2
+
+  // CHECK-SANITIZE:                   cont:
+  // CHECK-SANITIZE-NEXT:                call void @llvm.assume(i1 true) [ "align"(i8** %[[X_RELOADED]], i64 %[[ALIGNMENT]]) ]
+  // CHECK-NEXT:                         ret i8** %[[X_RELOADED]]
+  // CHECK-NEXT:                       }
   return x;
 }
 
Index: clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
===================================================================
--- clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
+++ clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
@@ -8,15 +8,37 @@
 
 char **__attribute__((alloc_align(2)))
 passthrough(char **x, unsigned long alignment) {
-  // CHECK:      define{{.*}} i8** @[[PASSTHROUGH:.*]](i8** noundef %[[X:.*]], i64 noundef %[[ALIGNMENT:.*]])
-  // CHECK-NEXT: entry:
-  // CHECK-NEXT:   %[[X_ADDR:.*]] = alloca i8**, align 8
-  // CHECK-NEXT:   %[[ALIGNMENT_ADDR:.*]] = alloca i64, align 8
-  // CHECK-NEXT:   store i8** %[[X]], i8*** %[[X_ADDR]], align 8
-  // CHECK-NEXT:   store i64 %[[ALIGNMENT]], i64* %[[ALIGNMENT_ADDR]], align 8
-  // CHECK-NEXT:   %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8
-  // CHECK-NEXT:   ret i8** %[[X_RELOADED]]
-  // CHECK-NEXT: }
+  // CHECK:                           define{{.*}} i8** @[[PASSTHROUGH:.*]](i8** noundef %[[X:.*]], i64 noundef %[[ALIGNMENT:.*]])
+  // CHECK-NEXT:                      entry:
+  // CHECK-SANITIZE-NEXT:               %return.sloc.ptr = alloca i8*, align 8
+  // CHECK-NEXT:                        %[[X_ADDR:.*]] = alloca i8**, align 8
+  // CHECK-NEXT:                        %[[ALIGNMENT_ADDR:.*]] = alloca i64, align 8
+  // CHECK-SANITIZE-NEXT:               store i8* null, i8** %return.sloc.ptr, align 8
+  // CHECK-NEXT:                        store i8** %[[X]], i8*** %[[X_ADDR]], align 8
+  // CHECK-NEXT:                        store i64 %[[ALIGNMENT]], i64* %[[ALIGNMENT_ADDR]], align 8
+  // CHECK-SANITIZE-NEXT:               store i8* bitcast ({ [160 x i8]*, i32, i32 }* @0 to i8*), i8** %return.sloc.ptr, align 8
+  // CHECK-NEXT:                        %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8
+  // CHECK-SANITIZE-NEXT:               %ptrint = ptrtoint i8** %0 to i64
+  // CHECK-SANITIZE-NEXT:               %[[SUBBED_THING:.*]] = sub i64 %alignment, 1
+  // CHECK-SANITIZE-NEXT:               %maskedptr = and i64 %ptrint, %[[SUBBED_THING]]
+  // CHECK-SANITIZE-NEXT:               %maskcond = icmp eq i64 %maskedptr, 0
+  // CHECK-SANITIZE-NEXT:               %[[PTRTOINT:.*]] = ptrtoint i8** %0 to i64, !nosanitize !2
+  // CHECK-SANITIZE-NORECOVER-NEXT:     br i1 %maskcond, label %cont, label %handler.alignment_assumption, !prof !3, !nosanitize !2
+  // CHECK-SANITIZE-TRAP-NEXT:          br i1 %maskcond, label %cont, label %trap, !nosanitize !2
+
+  // CHECK-SANITIZE-ANYRECOVER:        handler.alignment_assumption:                     ; preds = %entry
+  // CHECK-SANITIZE-NORECOVER-NEXT:     call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ { [160 x i8]*, i32, i32 }, { [160 x i8]*, i32, i32 }, { i16, i16, [10 x i8] }* }* @2 to i8*), i64 %[[PTRTOINT]], i64 %alignment, i64 0) #3, !nosanitize !2
+  // CHECK-SANITIZE-NORECOVER-NEXT:     unreachable, !nosanitize !2
+  // CHECK-SANITIZE-RECOVER-NEXT:       call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ { [160 x i8]*, i32, i32 }, { [160 x i8]*, i32, i32 }, { i16, i16, [10 x i8] }* }* @2 to i8*), i64 %[[PTRTOINT]], i64 %alignment, i64 0) #3, !nosanitize !2
+  // CHECK-SANITIZE-RECOVER-NEXT:       br label %cont, !nosanitize !2
+  // CHECK-SANITIZE-TRAP:             trap:
+  // CHECK-SANITIZE-TRAP-NEXT:           call void @llvm.ubsantrap(i8 23) #3, !nosanitize !2
+  // CHECK-SANITIZE-TRAP-NEXT:           unreachable, !nosanitize !2
+
+  // CHECK-SANITIZE:                  cont:
+  // CHECK-SANITIZE:                    call void @llvm.assume(i1 true) [ "align"(i8** %0, i64 %alignment) ]
+  // CHECK-NEXT:                        ret i8** %[[X_RELOADED]]
+  // CHECK-NEXT:                      }
   return x;
 }
 
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -671,7 +671,9 @@
 bool CodeGenFunction::requiresReturnValueCheck() const {
   return requiresReturnValueNullabilityCheck() ||
          (SanOpts.has(SanitizerKind::ReturnsNonnullAttribute) && CurCodeDecl &&
-          CurCodeDecl->getAttr<ReturnsNonNullAttr>());
+          CurCodeDecl->getAttr<ReturnsNonNullAttr>()) ||
+         (SanOpts.has(SanitizerKind::Alignment) && CurCodeDecl &&
+          CurCodeDecl->getAttr<AllocAlignAttr>());
 }
 
 static bool matchesStlAllocatorFn(const Decl *D, const ASTContext &Ctx) {
Index: clang/lib/CodeGen/CGCall.cpp
===================================================================
--- clang/lib/CodeGen/CGCall.cpp
+++ clang/lib/CodeGen/CGCall.cpp
@@ -3681,6 +3681,21 @@
   if (ReturnBlock.isValid() && ReturnBlock.getBlock()->use_empty())
     return;
 
+  const AllocAlignAttr *AA = CurCodeDecl->getAttr<AllocAlignAttr>();
+  if (SanOpts.has(SanitizerKind::Alignment) && AA) {
+    const FunctionDecl *F = dyn_cast<FunctionDecl>(CurCodeDecl);
+    if (F) {
+      unsigned PI = AA->getParamIndex().getLLVMIndex();
+      llvm::Value *Alignment = CurFn->getArg(PI);
+      emitAlignmentAssumption(RV, FnRetTy,
+                              // TODO: this first location seems like it should
+                              // be the _return_ statement is, but I'm not quite
+                              // sure how to figure that out from context here?
+                              AA->getLocation(), AA->getLocation(), Alignment,
+                              nullptr);
+    }
+  }
+
   ReturnsNonNullAttr *RetNNAttr = nullptr;
   if (SanOpts.has(SanitizerKind::ReturnsNonnullAttribute))
     RetNNAttr = CurCodeDecl->getAttr<ReturnsNonNullAttr>();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to