yronglin updated this revision to Diff 524673.
yronglin added a comment.

Try fix test.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D151121

Files:
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/catch-alignment-assumption-array.c
  
clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-polymorphism-no-opaque-ptr.cpp

Index: clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-polymorphism-no-opaque-ptr.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-polymorphism-no-opaque-ptr.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -no-opaque-pointers -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -no-opaque-pointers -fsanitize=alignment -fno-sanitize-recover=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER,CHECK-SANITIZE-UNREACHABLE
+// RUN: %clang_cc1 -no-opaque-pointers -fsanitize=alignment -fsanitize-recover=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
+// RUN: %clang_cc1 -no-opaque-pointers -fsanitize=alignment -fsanitize-trap=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE
+
+// CHECK-SANITIZE-ANYRECOVER: @[[CHAR:.*]] = {{.*}} c"'B *'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 35 }, {{.*}} @[[CHAR]] }
+
+struct A { int n; };
+struct B { int n; };
+struct C : A, B {};
+
+void *f(C *c) {
+  // CHECK:                             define {{.*}} i8* @{{.*}}(%struct.C* noundef %[[C:.*]]) {{.*}} {
+  // CHECK-NEXT:                        [[ENTRY:.*]]:
+  // CHECK-NEXT:                          %[[C_ADDR:.*]] = alloca %struct.C*
+  // CHECK-NEXT:                          store  %struct.C* %[[C]], %struct.C** %[[C_ADDR]]
+  // CHECK-NEXT:                          %[[C_RELOAD:.*]] = load %struct.C*, %struct.C** %[[C_ADDR]]
+  // CHECK-NEXT:                          %[[IS_NULL:.*]] = icmp eq %struct.C* %[[C_RELOAD]], null
+  // CHECK-NEXT:                          br i1 %[[IS_NULL]], label %[[CAST_END:[^,]+]], label %[[CAST_NOT_NULL:[^,]+]]
+  // CHECK:                             [[CAST_NOT_NULL]]:
+  // CHECK-NOSANITIZE-NEXT:               %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %[[C_RELOAD]], i64 4
+  // CHECK-NOSANITIZE-NEXT:               br label %[[CAST_END]]
+  // CHECK-SANITIZE-NEXT:                 %[[PTRTOINT:.*]] = ptrtoint %struct.C* %[[C_RELOAD]] to i64
+  // CHECK-SANITIZE-NEXT:                 %[[MASKEDPTR:.*]] = and i64 %[[PTRTOINT]], 3
+  // CHECK-SANITIZE-NEXT:                 %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
+  // CHECK-SANITIZE-NEXT:                 br i1 %[[MASKCOND]], label %[[CONT:[^,]+]], label %[[HANDLER_TYPE_MISMATCH:[^,]+]]
+  // CHECK-SANITIZE:                    [[HANDLER_TYPE_MISMATCH]]:
+  // CHECK-SANITIZE-NORECOVER-NEXT:       call void @__ubsan_handle_type_mismatch_v1_abort(
+  // CHECK-SANITIZE-RECOVER-NEXT:         call void @__ubsan_handle_type_mismatch_v1(
+  // CHECK-SANITIZE-TRAP-NEXT:            call void @llvm.ubsantrap(
+  // CHECK-SANITIZE-UNREACHABLE-NEXT:     unreachable
+  // CHECK-SANITIZE:                    [[CONT]]:
+  // CHECK-SANITIZE-NEXT:                 %[[CONT_BITCAST:.*]] = bitcast %struct.C* %0 to i8*
+  // CHECK-SANITIZE-NEXT:                 %[[ADD_PTR:.*]] = getelementptr inbounds i8, i8* %[[CONT_BITCAST]], i64 4
+  // CHECK-SANITIZE-NEXT:                 %[[CONT_BITCAST1:.*]] = bitcast i8* %[[ADD_PTR]] to %struct.B*
+  // CHECK-SANITIZE-NEXT:                 br label %[[CAST_END]]
+  // CHECK:                             [[CAST_END]]:
+  // CHECK-NOSANITIZE-NEXT:               %[[CAST_RESULT:.*]] = phi %struct.B* [ %[[CONT_BITCAST1]], %[[CAST_NOT_NULL]] ], [ null, %[[ENTRY]] ]
+  // CHECK-NOSANITIZE-NEXT:               call void @llvm.assume(i1 true) [ "align"(ptr %[[CAST_RESULT]], i64 8) ]
+  // CHECK-NOSANITIZE-NEXT:               ret ptr %[[CAST_RESULT]]
+  // CHECK-NOSANITIZE-NEXT:              }
+  // CHECK-SANITIZE-NEXT:                 %[[CAST_RESULT:.*]] = phi %struct.B* [ %[[CONT_BITCAST1]], %[[CONT]] ], [ null, %[[ENTRY]] ]
+  // CHECK-SANITIZE-NEXT:                 %[[CAST_RESULT1:.*]] = bitcast %struct.B* %[[CAST_RESULT]] to i8*
+  // CHECK-SANITIZE-NEXT:                 %[[PTRINT:.*]] = ptrtoint i8* %[[CAST_RESULT1]] to i64
+  // CHECK-SANITIZE-NEXT:                 %[[MASKEDPTR:.*]] = and i64 %[[PTRINT]], 7
+  // CHECK-SANITIZE-NEXT:                 %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
+  // CHECK-SANITIZE-NEXT:                 %[[PTRINT_DUP:.*]] = ptrtoint i8* %[[CAST_RESULT1]] to i64
+  // CHECK-SANITIZE-NEXT:                 br i1 %[[MASKCOND]], label %[[CONT1:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}}
+  // CHECK-SANITIZE:                    [[HANDLER_ALIGNMENT_ASSUMPTION]]:
+  // CHECK-SANITIZE-NORECOVER-NEXT:       call void @__ubsan_handle_alignment_assumption_abort(i8* {{.*}}@[[LINE_100_ALIGNMENT_ASSUMPTION]]{{.*}}, i64 %[[PTRINT_DUP]], i64 8, i64 0){{.*}}
+  // CHECK-SANITIZE-RECOVER-NEXT:         call void @__ubsan_handle_alignment_assumption(i8* {{.*}}@[[LINE_100_ALIGNMENT_ASSUMPTION]]{{.*}}, i64 %[[PTRINT_DUP]], i64 8, i64 0){{.*}}
+  // CHECK-SANITIZE-TRAP-NEXT:            call void @llvm.ubsantrap(i8 23){{.*}}
+  // CHECK-SANITIZE-UNREACHABLE-NEXT:     unreachable
+  // CHECK-SANITIZE:                    [[CONT1]]:
+  // CHECK-SANITIZE-NEXT:                 call void @llvm.assume(i1 true) [ "align"(i8* %[[CAST_RESULT1]], i64 8) ]
+  // CHECK-SANITIZE-NEXT:                 ret i8* %[[CAST_RESULT1]]
+  // CHECK-SANITIZE-NEXT:                }
+#line 100
+  return __builtin_assume_aligned((B*)c, 8);
+}
Index: clang/test/CodeGen/catch-alignment-assumption-array.c
===================================================================
--- clang/test/CodeGen/catch-alignment-assumption-array.c
+++ clang/test/CodeGen/catch-alignment-assumption-array.c
@@ -3,7 +3,7 @@
 // RUN: %clang_cc1 -fsanitize=alignment -fsanitize-recover=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
 // RUN: %clang_cc1 -fsanitize=alignment -fsanitize-trap=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE
 
-// CHECK-SANITIZE-ANYRECOVER: @[[CHAR:.*]] = {{.*}} c"'char *'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[CHAR:.*]] = {{.*}} c"'char[1]'\00" }
 // CHECK-SANITIZE-ANYRECOVER: @[[ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 30, i32 35 }, {{.*}} @[[CHAR]] }
 
 void *caller(void) {
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -8012,17 +8012,8 @@
   if (checkArgCountRange(*this, TheCall, 2, 3))
     return true;
 
-  unsigned NumArgs = TheCall->getNumArgs();
-  Expr *FirstArg = TheCall->getArg(0);
-
-  {
-    ExprResult FirstArgResult =
-        DefaultFunctionArrayLvalueConversion(FirstArg);
-    if (checkBuiltinArgument(*this, TheCall, 0))
-      return true;
-    /// In-place updation of FirstArg by checkBuiltinArgument is ignored.
-    TheCall->setArg(0, FirstArgResult.get());
-  }
+  if (checkBuiltinArgument(*this, TheCall, 0))
+    return true;
 
   // The alignment must be a constant integer.
   Expr *SecondArg = TheCall->getArg(1);
@@ -8042,7 +8033,7 @@
           << SecondArg->getSourceRange() << Sema::MaximumAlignment;
   }
 
-  if (NumArgs > 2) {
+  if (TheCall->getNumArgs() > 2) {
     Expr *ThirdArg = TheCall->getArg(2);
     if (convertArgumentToType(*this, ThirdArg, Context.getSizeType()))
       return true;
Index: clang/lib/CodeGen/CodeGenFunction.h
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.h
+++ clang/lib/CodeGen/CodeGenFunction.h
@@ -3188,7 +3188,7 @@
   PeepholeProtection protectFromPeepholes(RValue rvalue);
   void unprotectFromPeepholes(PeepholeProtection protection);
 
-  void emitAlignmentAssumptionCheck(llvm::Value *Ptr, QualType Ty,
+  void emitAlignmentAssumptionCheck(llvm::Value *Ptr, QualType WrittenTy,
                                     SourceLocation Loc,
                                     SourceLocation AssumptionLoc,
                                     llvm::Value *Alignment,
@@ -3196,12 +3196,12 @@
                                     llvm::Value *TheCheck,
                                     llvm::Instruction *Assumption);
 
-  void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty,
+  void emitAlignmentAssumption(llvm::Value *PtrValue, QualType PtrTy,
                                SourceLocation Loc, SourceLocation AssumptionLoc,
                                llvm::Value *Alignment,
                                llvm::Value *OffsetValue = nullptr);
 
-  void emitAlignmentAssumption(llvm::Value *PtrValue, const Expr *E,
+  void emitAlignmentAssumption(llvm::Value *PtrValue, const Expr *PtrExpr,
                                SourceLocation AssumptionLoc,
                                llvm::Value *Alignment,
                                llvm::Value *OffsetValue = nullptr);
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -2409,7 +2409,8 @@
 }
 
 void CodeGenFunction::emitAlignmentAssumption(llvm::Value *PtrValue,
-                                              QualType Ty, SourceLocation Loc,
+                                              QualType WrittenTy,
+                                              SourceLocation Loc,
                                               SourceLocation AssumptionLoc,
                                               llvm::Value *Alignment,
                                               llvm::Value *OffsetValue) {
@@ -2444,19 +2445,24 @@
 
   if (!SanOpts.has(SanitizerKind::Alignment))
     return;
-  emitAlignmentAssumptionCheck(PtrValue, Ty, Loc, AssumptionLoc, Alignment,
-                               OffsetValue, TheCheck, Assumption);
+  emitAlignmentAssumptionCheck(PtrValue, WrittenTy, Loc, AssumptionLoc,
+                               Alignment, OffsetValue, TheCheck, Assumption);
 }
 
 void CodeGenFunction::emitAlignmentAssumption(llvm::Value *PtrValue,
-                                              const Expr *E,
+                                              const Expr *PtrExpr,
                                               SourceLocation AssumptionLoc,
                                               llvm::Value *Alignment,
                                               llvm::Value *OffsetValue) {
-  QualType Ty = E->getType();
-  SourceLocation Loc = E->getExprLoc();
-
-  emitAlignmentAssumption(PtrValue, Ty, Loc, AssumptionLoc, Alignment,
+  // Written type used to build TypeDescriptor.
+  QualType WrittenTy;
+  if (auto *CE = dyn_cast<CastExpr>(PtrExpr)) {
+    WrittenTy = CE->getSubExprAsWritten()->getType();
+  } else {
+    WrittenTy = PtrExpr->getType();
+  }
+  SourceLocation Loc = PtrExpr->getExprLoc();
+  emitAlignmentAssumption(PtrValue, WrittenTy, Loc, AssumptionLoc, Alignment,
                           OffsetValue);
 }
 
@@ -2806,7 +2812,7 @@
 //  It should be the location where the __attribute__((assume_aligned))
 //  was written e.g.
 void CodeGenFunction::emitAlignmentAssumptionCheck(
-    llvm::Value *Ptr, QualType Ty, SourceLocation Loc,
+    llvm::Value *Ptr, QualType WrittenTy, SourceLocation Loc,
     SourceLocation SecondaryLoc, llvm::Value *Alignment,
     llvm::Value *OffsetValue, llvm::Value *TheCheck,
     llvm::Instruction *Assumption) {
@@ -2825,8 +2831,13 @@
 
   // Don't check pointers to volatile data. The behavior here is implementation-
   // defined.
-  if (Ty->getPointeeType().isVolatileQualified())
+  // The volatile qualifier on PtrTy will be ignored in Sema, we try to find
+  // volatile in WrittenTy as a workaround.
+  if ((WrittenTy->isPointerType() &&
+       WrittenTy->getPointeeType().isVolatileQualified()) ||
+      (WrittenTy->isArrayType() && WrittenTy.isVolatileQualified())) {
     return;
+  }
 
   // We need to temorairly remove the assumption so we can insert the
   // sanitizer check before it, else the check will be dropped by optimizations.
@@ -2840,7 +2851,7 @@
 
     llvm::Constant *StaticData[] = {EmitCheckSourceLocation(Loc),
                                     EmitCheckSourceLocation(SecondaryLoc),
-                                    EmitCheckTypeDescriptor(Ty)};
+                                    EmitCheckTypeDescriptor(WrittenTy)};
     llvm::Value *DynamicData[] = {EmitCheckValue(Ptr),
                                   EmitCheckValue(Alignment),
                                   EmitCheckValue(OffsetValue)};
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to