mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-13 19:24:21 +00:00
[clang][UBSan] Sanitization for alignment assumptions.
Summary: UB isn't nice. It's cool and powerful, but not nice. Having a way to detect it is nice though. [[ https://wg21.link/p1007r3 | P1007R3: std::assume_aligned ]] / http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1007r2.pdf says: ``` We propose to add this functionality via a library function instead of a core language attribute. ... If the pointer passed in is not aligned to at least N bytes, calling assume_aligned results in undefined behaviour. ``` This differential teaches clang to sanitize all the various variants of this assume-aligned attribute. Requires D54588 for LLVM IRBuilder changes. The compiler-rt part is D54590. This is a second commit, the original one was r351105, which was mass-reverted in r351159 because 2 compiler-rt tests were failing. Reviewers: ABataev, craig.topper, vsk, rsmith, rnk, #sanitizers, erichkeane, filcab, rjmccall Reviewed By: rjmccall Subscribers: chandlerc, ldionne, EricWF, mclow.lists, cfe-commits, bkramer Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D54589 llvm-svn: 351177
This commit is contained in:
parent
6d0413fe23
commit
bd1c087019
@ -321,6 +321,49 @@ Undefined Behavior Sanitizer (UBSan)
|
||||
* The Implicit Conversion Sanitizer (``-fsanitize=implicit-conversion``) has
|
||||
learned to sanitize compound assignment operators.
|
||||
|
||||
* ``alignment`` check has learned to sanitize the assume_aligned-like attributes:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
typedef char **__attribute__((align_value(1024))) aligned_char;
|
||||
struct ac_struct {
|
||||
aligned_char a;
|
||||
};
|
||||
char **load_from_ac_struct(struct ac_struct *x) {
|
||||
return x->a; // <- check that loaded 'a' is aligned
|
||||
}
|
||||
|
||||
char **passthrough(__attribute__((align_value(1024))) char **x) {
|
||||
return x; // <- check the pointer passed as function argument
|
||||
}
|
||||
|
||||
char **__attribute__((alloc_align(2)))
|
||||
alloc_align(int size, unsigned long alignment);
|
||||
|
||||
char **caller(int size) {
|
||||
return alloc_align(size, 1024); // <- check returned pointer
|
||||
}
|
||||
|
||||
char **__attribute__((assume_aligned(1024))) get_ptr();
|
||||
|
||||
char **caller2() {
|
||||
return get_ptr(); // <- check returned pointer
|
||||
}
|
||||
|
||||
void *caller3(char **x) {
|
||||
return __builtin_assume_aligned(x, 1024); // <- check returned pointer
|
||||
}
|
||||
|
||||
void *caller4(char **x, unsigned long offset) {
|
||||
return __builtin_assume_aligned(x, 1024, offset); // <- check returned pointer accounting for the offest
|
||||
}
|
||||
|
||||
void process(char *data, int width) {
|
||||
#pragma omp for simd aligned(data : 1024) // <- aligned clause will be checked.
|
||||
for (int x = 0; x < width; x++)
|
||||
data[x] *= data[x];
|
||||
}
|
||||
|
||||
Core Analysis Improvements
|
||||
==========================
|
||||
|
||||
|
@ -72,7 +72,7 @@ Available checks
|
||||
Available checks are:
|
||||
|
||||
- ``-fsanitize=alignment``: Use of a misaligned pointer or creation
|
||||
of a misaligned reference.
|
||||
of a misaligned reference. Also sanitizes assume_aligned-like attributes.
|
||||
- ``-fsanitize=bool``: Load of a ``bool`` value which is neither
|
||||
``true`` nor ``false``.
|
||||
- ``-fsanitize=builtin``: Passing invalid values to compiler builtins.
|
||||
|
@ -1904,15 +1904,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
|
||||
return RValue::get(Result);
|
||||
}
|
||||
case Builtin::BI__builtin_assume_aligned: {
|
||||
Value *PtrValue = EmitScalarExpr(E->getArg(0));
|
||||
const Expr *Ptr = E->getArg(0);
|
||||
Value *PtrValue = EmitScalarExpr(Ptr);
|
||||
Value *OffsetValue =
|
||||
(E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : nullptr;
|
||||
|
||||
Value *AlignmentValue = EmitScalarExpr(E->getArg(1));
|
||||
ConstantInt *AlignmentCI = cast<ConstantInt>(AlignmentValue);
|
||||
unsigned Alignment = (unsigned) AlignmentCI->getZExtValue();
|
||||
unsigned Alignment = (unsigned)AlignmentCI->getZExtValue();
|
||||
|
||||
EmitAlignmentAssumption(PtrValue, Alignment, OffsetValue);
|
||||
EmitAlignmentAssumption(PtrValue, Ptr, /*The expr loc is sufficient.*/ SourceLocation(),
|
||||
Alignment, OffsetValue);
|
||||
return RValue::get(PtrValue);
|
||||
}
|
||||
case Builtin::BI__assume:
|
||||
|
@ -2410,7 +2410,10 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
|
||||
if (!AVAttr)
|
||||
if (const auto *TOTy = dyn_cast<TypedefType>(OTy))
|
||||
AVAttr = TOTy->getDecl()->getAttr<AlignValueAttr>();
|
||||
if (AVAttr) {
|
||||
if (AVAttr && !SanOpts.has(SanitizerKind::Alignment)) {
|
||||
// If alignment-assumption sanitizer is enabled, we do *not* add
|
||||
// alignment attribute here, but emit normal alignment assumption,
|
||||
// so the UBSAN check could function.
|
||||
llvm::Value *AlignmentValue =
|
||||
EmitScalarExpr(AVAttr->getAlignment());
|
||||
llvm::ConstantInt *AlignmentCI =
|
||||
@ -4535,13 +4538,14 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
|
||||
|
||||
llvm::Value *Alignment = EmitScalarExpr(AA->getAlignment());
|
||||
llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(Alignment);
|
||||
EmitAlignmentAssumption(Ret.getScalarVal(), AlignmentCI->getZExtValue(),
|
||||
OffsetValue);
|
||||
EmitAlignmentAssumption(Ret.getScalarVal(), RetTy, Loc, AA->getLocation(),
|
||||
AlignmentCI->getZExtValue(), OffsetValue);
|
||||
} else if (const auto *AA = TargetDecl->getAttr<AllocAlignAttr>()) {
|
||||
llvm::Value *ParamVal =
|
||||
CallArgs[AA->getParamIndex().getLLVMIndex()].getRValue(
|
||||
*this).getScalarVal();
|
||||
EmitAlignmentAssumption(Ret.getScalarVal(), ParamVal);
|
||||
llvm::Value *AlignmentVal = CallArgs[AA->getParamIndex().getLLVMIndex()]
|
||||
.getRValue(*this)
|
||||
.getScalarVal();
|
||||
EmitAlignmentAssumption(Ret.getScalarVal(), RetTy, Loc, AA->getLocation(),
|
||||
AlignmentVal);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -258,8 +258,11 @@ public:
|
||||
AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
|
||||
} else {
|
||||
// Assumptions for function parameters are emitted at the start of the
|
||||
// function, so there is no need to repeat that here.
|
||||
if (isa<ParmVarDecl>(VD))
|
||||
// function, so there is no need to repeat that here,
|
||||
// unless the alignment-assumption sanitizer is enabled,
|
||||
// then we prefer the assumption over alignment attribute
|
||||
// on IR function param.
|
||||
if (isa<ParmVarDecl>(VD) && !CGF.SanOpts.has(SanitizerKind::Alignment))
|
||||
return;
|
||||
|
||||
AVAttr = VD->getAttr<AlignValueAttr>();
|
||||
@ -276,7 +279,8 @@ public:
|
||||
|
||||
Value *AlignmentValue = CGF.EmitScalarExpr(AVAttr->getAlignment());
|
||||
llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
|
||||
CGF.EmitAlignmentAssumption(V, AlignmentCI->getZExtValue());
|
||||
CGF.EmitAlignmentAssumption(V, E, AVAttr->getLocation(),
|
||||
AlignmentCI->getZExtValue());
|
||||
}
|
||||
|
||||
/// EmitLoadOfLValue - Given an expression with complex type that represents a
|
||||
|
@ -1472,7 +1472,8 @@ static void emitAlignedClause(CodeGenFunction &CGF,
|
||||
"alignment is not power of 2");
|
||||
if (Alignment != 0) {
|
||||
llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
|
||||
CGF.EmitAlignmentAssumption(PtrValue, Alignment);
|
||||
CGF.EmitAlignmentAssumption(
|
||||
PtrValue, E, /*No second loc needed*/ SourceLocation(), Alignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2207,6 +2207,49 @@ void CodeGenFunction::unprotectFromPeepholes(PeepholeProtection protection) {
|
||||
protection.Inst->eraseFromParent();
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue,
|
||||
QualType Ty, SourceLocation Loc,
|
||||
SourceLocation AssumptionLoc,
|
||||
llvm::Value *Alignment,
|
||||
llvm::Value *OffsetValue) {
|
||||
llvm::Value *TheCheck;
|
||||
llvm::Instruction *Assumption = Builder.CreateAlignmentAssumption(
|
||||
CGM.getDataLayout(), PtrValue, Alignment, OffsetValue, &TheCheck);
|
||||
if (SanOpts.has(SanitizerKind::Alignment)) {
|
||||
EmitAlignmentAssumptionCheck(PtrValue, Ty, Loc, AssumptionLoc, Alignment,
|
||||
OffsetValue, TheCheck, Assumption);
|
||||
}
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue,
|
||||
QualType Ty, SourceLocation Loc,
|
||||
SourceLocation AssumptionLoc,
|
||||
unsigned Alignment,
|
||||
llvm::Value *OffsetValue) {
|
||||
llvm::Value *TheCheck;
|
||||
llvm::Instruction *Assumption = Builder.CreateAlignmentAssumption(
|
||||
CGM.getDataLayout(), PtrValue, Alignment, OffsetValue, &TheCheck);
|
||||
if (SanOpts.has(SanitizerKind::Alignment)) {
|
||||
llvm::Value *AlignmentVal = llvm::ConstantInt::get(IntPtrTy, Alignment);
|
||||
EmitAlignmentAssumptionCheck(PtrValue, Ty, Loc, AssumptionLoc, AlignmentVal,
|
||||
OffsetValue, TheCheck, Assumption);
|
||||
}
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue,
|
||||
const Expr *E,
|
||||
SourceLocation AssumptionLoc,
|
||||
unsigned Alignment,
|
||||
llvm::Value *OffsetValue) {
|
||||
if (auto *CE = dyn_cast<CastExpr>(E))
|
||||
E = CE->getSubExprAsWritten();
|
||||
QualType Ty = E->getType();
|
||||
SourceLocation Loc = E->getExprLoc();
|
||||
|
||||
EmitAlignmentAssumption(PtrValue, Ty, Loc, AssumptionLoc, Alignment,
|
||||
OffsetValue);
|
||||
}
|
||||
|
||||
llvm::Value *CodeGenFunction::EmitAnnotationCall(llvm::Value *AnnotationFn,
|
||||
llvm::Value *AnnotatedVal,
|
||||
StringRef AnnotationStr,
|
||||
@ -2459,6 +2502,61 @@ void CodeGenFunction::EmitMultiVersionResolver(
|
||||
Builder.ClearInsertionPoint();
|
||||
}
|
||||
|
||||
// Loc - where the diagnostic will point, where in the source code this
|
||||
// alignment has failed.
|
||||
// SecondaryLoc - if present (will be present if sufficiently different from
|
||||
// Loc), the diagnostic will additionally point a "Note:" to this location.
|
||||
// It should be the location where the __attribute__((assume_aligned))
|
||||
// was written e.g.
|
||||
void CodeGenFunction::EmitAlignmentAssumptionCheck(
|
||||
llvm::Value *Ptr, QualType Ty, SourceLocation Loc,
|
||||
SourceLocation SecondaryLoc, llvm::Value *Alignment,
|
||||
llvm::Value *OffsetValue, llvm::Value *TheCheck,
|
||||
llvm::Instruction *Assumption) {
|
||||
assert(Assumption && isa<llvm::CallInst>(Assumption) &&
|
||||
cast<llvm::CallInst>(Assumption)->getCalledValue() ==
|
||||
llvm::Intrinsic::getDeclaration(
|
||||
Builder.GetInsertBlock()->getParent()->getParent(),
|
||||
llvm::Intrinsic::assume) &&
|
||||
"Assumption should be a call to llvm.assume().");
|
||||
assert(&(Builder.GetInsertBlock()->back()) == Assumption &&
|
||||
"Assumption should be the last instruction of the basic block, "
|
||||
"since the basic block is still being generated.");
|
||||
|
||||
if (!SanOpts.has(SanitizerKind::Alignment))
|
||||
return;
|
||||
|
||||
// Don't check pointers to volatile data. The behavior here is implementation-
|
||||
// defined.
|
||||
if (Ty->getPointeeType().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.
|
||||
Assumption->removeFromParent();
|
||||
|
||||
{
|
||||
SanitizerScope SanScope(this);
|
||||
|
||||
if (!OffsetValue)
|
||||
OffsetValue = Builder.getInt1(0); // no offset.
|
||||
|
||||
llvm::Constant *StaticData[] = {EmitCheckSourceLocation(Loc),
|
||||
EmitCheckSourceLocation(SecondaryLoc),
|
||||
EmitCheckTypeDescriptor(Ty)};
|
||||
llvm::Value *DynamicData[] = {EmitCheckValue(Ptr),
|
||||
EmitCheckValue(Alignment),
|
||||
EmitCheckValue(OffsetValue)};
|
||||
EmitCheck({std::make_pair(TheCheck, SanitizerKind::Alignment)},
|
||||
SanitizerHandler::AlignmentAssumption, StaticData, DynamicData);
|
||||
}
|
||||
|
||||
// We are now in the (new, empty) "cont" basic block.
|
||||
// Reintroduce the assumption.
|
||||
Builder.Insert(Assumption);
|
||||
// FIXME: Assumption still has it's original basic block as it's Parent.
|
||||
}
|
||||
|
||||
llvm::DebugLoc CodeGenFunction::SourceLocToDebugLoc(SourceLocation Location) {
|
||||
if (CGDebugInfo *DI = getDebugInfo())
|
||||
return DI->SourceLocToDebugLoc(Location);
|
||||
|
@ -131,6 +131,7 @@ enum TypeEvaluationKind {
|
||||
SANITIZER_CHECK(ShiftOutOfBounds, shift_out_of_bounds, 0) \
|
||||
SANITIZER_CHECK(SubOverflow, sub_overflow, 0) \
|
||||
SANITIZER_CHECK(TypeMismatch, type_mismatch, 1) \
|
||||
SANITIZER_CHECK(AlignmentAssumption, alignment_assumption, 0) \
|
||||
SANITIZER_CHECK(VLABoundNotPositive, vla_bound_not_positive, 0)
|
||||
|
||||
enum SanitizerHandler {
|
||||
@ -2633,12 +2634,6 @@ public:
|
||||
ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,
|
||||
bool isInc, bool isPre);
|
||||
|
||||
void EmitAlignmentAssumption(llvm::Value *PtrValue, unsigned Alignment,
|
||||
llvm::Value *OffsetValue = nullptr) {
|
||||
Builder.CreateAlignmentAssumption(CGM.getDataLayout(), PtrValue, Alignment,
|
||||
OffsetValue);
|
||||
}
|
||||
|
||||
/// Converts Location to a DebugLoc, if debug information is enabled.
|
||||
llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location);
|
||||
|
||||
@ -2802,11 +2797,27 @@ public:
|
||||
PeepholeProtection protectFromPeepholes(RValue rvalue);
|
||||
void unprotectFromPeepholes(PeepholeProtection protection);
|
||||
|
||||
void EmitAlignmentAssumption(llvm::Value *PtrValue, llvm::Value *Alignment,
|
||||
llvm::Value *OffsetValue = nullptr) {
|
||||
Builder.CreateAlignmentAssumption(CGM.getDataLayout(), PtrValue, Alignment,
|
||||
OffsetValue);
|
||||
}
|
||||
void EmitAlignmentAssumptionCheck(llvm::Value *Ptr, QualType Ty,
|
||||
SourceLocation Loc,
|
||||
SourceLocation AssumptionLoc,
|
||||
llvm::Value *Alignment,
|
||||
llvm::Value *OffsetValue,
|
||||
llvm::Value *TheCheck,
|
||||
llvm::Instruction *Assumption);
|
||||
|
||||
void EmitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty,
|
||||
SourceLocation Loc, SourceLocation AssumptionLoc,
|
||||
llvm::Value *Alignment,
|
||||
llvm::Value *OffsetValue = nullptr);
|
||||
|
||||
void EmitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty,
|
||||
SourceLocation Loc, SourceLocation AssumptionLoc,
|
||||
unsigned Alignment,
|
||||
llvm::Value *OffsetValue = nullptr);
|
||||
|
||||
void EmitAlignmentAssumption(llvm::Value *PtrValue, const Expr *E,
|
||||
SourceLocation AssumptionLoc, unsigned Alignment,
|
||||
llvm::Value *OffsetValue = nullptr);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Statement Emission
|
||||
|
@ -0,0 +1,40 @@
|
||||
// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-NOSANITIZE
|
||||
// RUN: %clang_cc1 -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 -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
|
||||
|
||||
typedef char **__attribute__((align_value(0x80000000))) aligned_char;
|
||||
|
||||
struct ac_struct {
|
||||
// CHECK: %[[STRUCT_AC_STRUCT:.*]] = type { i8** }
|
||||
aligned_char a;
|
||||
};
|
||||
|
||||
// CHECK-SANITIZE-ANYRECOVER: @[[ALIGNED_CHAR:.*]] = {{.*}} c"'aligned_char' (aka 'char **')\00" }
|
||||
// CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 13 }, {{.*}}* @[[ALIGNED_CHAR]] }
|
||||
|
||||
char **load_from_ac_struct(struct ac_struct *x) {
|
||||
// CHECK: define i8** @{{.*}}(%[[STRUCT_AC_STRUCT]]* %[[X:.*]])
|
||||
// CHECK-NEXT: [[ENTRY:.*]]:
|
||||
// CHECK-NEXT: %[[STRUCT_AC_STRUCT_ADDR:.*]] = alloca %[[STRUCT_AC_STRUCT]]*, align 8
|
||||
// CHECK-NEXT: store %[[STRUCT_AC_STRUCT]]* %[[X]], %[[STRUCT_AC_STRUCT]]** %[[STRUCT_AC_STRUCT_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[X_RELOADED:.*]] = load %[[STRUCT_AC_STRUCT]]*, %[[STRUCT_AC_STRUCT]]** %[[STRUCT_AC_STRUCT_ADDR]], align 8
|
||||
// CHECK: %[[A_ADDR:.*]] = getelementptr inbounds %[[STRUCT_AC_STRUCT]], %[[STRUCT_AC_STRUCT]]* %[[X_RELOADED]], i32 0, i32 0
|
||||
// CHECK: %[[A:.*]] = load i8**, i8*** %[[A_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[PTRINT:.*]] = ptrtoint i8** %[[A]] to i64
|
||||
// CHECK-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[PTRINT]], 2147483647
|
||||
// CHECK-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
|
||||
// CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8** %[[A]] to i64, !nosanitize
|
||||
// CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize
|
||||
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
|
||||
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 0){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 0){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
|
||||
// CHECK-SANITIZE: [[CONT]]:
|
||||
// CHECK-NEXT: call void @llvm.assume(i1 %[[MASKCOND]])
|
||||
// CHECK-NEXT: ret i8** %[[A]]
|
||||
// CHECK-NEXT: }
|
||||
#line 100
|
||||
return x->a;
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-NOSANITIZE
|
||||
// RUN: %clang_cc1 -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 -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: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[CHAR]] }
|
||||
|
||||
char **passthrough(__attribute__((align_value(0x80000000))) char **x) {
|
||||
// CHECK-NOSANITIZE: define i8** @{{.*}}(i8** align 536870912 %[[X:.*]])
|
||||
// CHECK-SANITIZE: define i8** @{{.*}}(i8** %[[X:.*]])
|
||||
// CHECK-NEXT: [[entry:.*]]:
|
||||
// CHECK-NEXT: %[[X_ADDR:.*]] = alloca i8**, align 8
|
||||
// CHECK-NEXT: store i8** %[[X]], i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-SANITIZE-NEXT: %[[PTRINT:.*]] = ptrtoint i8** %[[X_RELOADED]] to i64
|
||||
// CHECK-SANITIZE-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[PTRINT]], 2147483647
|
||||
// CHECK-SANITIZE-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
|
||||
// CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8** %[[X_RELOADED]] to i64, !nosanitize
|
||||
// CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize
|
||||
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
|
||||
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 0){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 0){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
|
||||
// CHECK-SANITIZE: [[CONT]]:
|
||||
// CHECK-SANITIZE-NEXT: call void @llvm.assume(i1 %[[MASKCOND]])
|
||||
// CHECK-NEXT: ret i8** %[[X_RELOADED]]
|
||||
// CHECK-NEXT: }
|
||||
#line 100
|
||||
return x;
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-NOSANITIZE
|
||||
// RUN: %clang_cc1 -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 -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: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[CHAR]] }
|
||||
|
||||
char **__attribute__((alloc_align(2)))
|
||||
passthrough(char **x, unsigned long alignment) {
|
||||
// CHECK: define i8** @[[PASSTHROUGH:.*]](i8** %[[X:.*]], i64 %[[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: }
|
||||
return x;
|
||||
}
|
||||
|
||||
char **caller(char **x, unsigned long alignment) {
|
||||
// CHECK: define i8** @{{.*}}(i8** %[[X:.*]], i64 %[[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: %[[ALIGNMENT_RELOADED:.*]] = load i64, i64* %[[ALIGNMENT_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[X_RETURNED:.*]] = call i8** @[[PASSTHROUGH]](i8** %[[X_RELOADED]], i64 %[[ALIGNMENT_RELOADED]])
|
||||
// CHECK-NEXT: %[[ISPOSITIVE:.*]] = icmp sgt i64 %[[ALIGNMENT_RELOADED]], 0
|
||||
// CHECK-NEXT: %[[POSITIVEMASK:.*]] = sub i64 %[[ALIGNMENT_RELOADED]], 1
|
||||
// CHECK-NEXT: %[[MASK:.*]] = select i1 %[[ISPOSITIVE]], i64 %[[POSITIVEMASK]], i64 0
|
||||
// CHECK-NEXT: %[[PTRINT:.*]] = ptrtoint i8** %[[X_RETURNED]] to i64
|
||||
// CHECK-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[PTRINT]], %[[MASK]]
|
||||
// CHECK-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
|
||||
// CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8** %[[X_RETURNED]] to i64, !nosanitize
|
||||
// CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize
|
||||
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
|
||||
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 %[[ALIGNMENT_RELOADED]], i64 0){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 %[[ALIGNMENT_RELOADED]], i64 0){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
|
||||
// CHECK-SANITIZE: [[CONT]]:
|
||||
// CHECK-NEXT: call void @llvm.assume(i1 %[[MASKCOND]])
|
||||
// CHECK-NEXT: ret i8** %[[X_RETURNED]]
|
||||
// CHECK-NEXT: }
|
||||
#line 100
|
||||
return passthrough(x, alignment);
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-NOSANITIZE
|
||||
// RUN: %clang_cc1 -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 -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: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[CHAR]] }
|
||||
|
||||
char **__attribute__((alloc_align(2)))
|
||||
passthrough(char **x, unsigned long alignment) {
|
||||
// CHECK: define i8** @[[PASSTHROUGH:.*]](i8** %[[X:.*]], i64 %[[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: }
|
||||
return x;
|
||||
}
|
||||
|
||||
char **caller(char **x) {
|
||||
// CHECK: define i8** @{{.*}}(i8** %[[X:.*]])
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: %[[X_ADDR:.*]] = alloca i8**, align 8
|
||||
// CHECK-NEXT: store i8** %[[X]], i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[X_RETURNED:.*]] = call i8** @[[PASSTHROUGH]](i8** %[[X_RELOADED]], i64 2147483648)
|
||||
// CHECK-NEXT: %[[PTRINT:.*]] = ptrtoint i8** %[[X_RETURNED]] to i64
|
||||
// CHECK-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[PTRINT]], 2147483647
|
||||
// CHECK-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
|
||||
// CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8** %[[X_RETURNED]] to i64, !nosanitize
|
||||
// CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize
|
||||
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
|
||||
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 0){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 0){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
|
||||
// CHECK-SANITIZE: [[CONT]]:
|
||||
// CHECK-NEXT: call void @llvm.assume(i1 %[[MASKCOND]])
|
||||
// CHECK-NEXT: ret i8** %[[X_RETURNED]]
|
||||
// CHECK-NEXT: }
|
||||
#line 100
|
||||
return passthrough(x, 0x80000000);
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-NOSANITIZE
|
||||
// RUN: %clang_cc1 -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 -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: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[CHAR]] }
|
||||
|
||||
char **__attribute__((assume_aligned(0x80000000, 42))) passthrough(char **x) {
|
||||
// CHECK: define i8** @[[PASSTHROUGH:.*]](i8** %[[X:.*]])
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: %[[X_ADDR:.*]] = alloca i8**, align 8
|
||||
// CHECK-NEXT: store i8** %[[X]], i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: ret i8** %[[X_RELOADED]]
|
||||
// CHECK-NEXT: }
|
||||
return x;
|
||||
}
|
||||
|
||||
char **caller(char **x) {
|
||||
// CHECK: define i8** @{{.*}}(i8** %[[X:.*]])
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: %[[X_ADDR:.*]] = alloca i8**, align 8
|
||||
// CHECK-NEXT: store i8** %[[X]], i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[X_RETURNED:.*]] = call i8** @[[PASSTHROUGH]](i8** %[[X_RELOADED]])
|
||||
// CHECK-NEXT: %[[PTRINT:.*]] = ptrtoint i8** %[[X_RETURNED]] to i64
|
||||
// CHECK-NEXT: %[[OFFSETPTR:.*]] = sub i64 %[[PTRINT]], 42
|
||||
// CHECK-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[OFFSETPTR]], 2147483647
|
||||
// CHECK-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
|
||||
// CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8** %[[X_RETURNED]] to i64, !nosanitize
|
||||
// CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize
|
||||
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
|
||||
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 42){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 42){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
|
||||
// CHECK-SANITIZE: [[CONT]]:
|
||||
// CHECK-NEXT: call void @llvm.assume(i1 %[[MASKCOND]])
|
||||
// CHECK-NEXT: ret i8** %[[X_RETURNED]]
|
||||
// CHECK-NEXT: }
|
||||
#line 100
|
||||
return passthrough(x);
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-NOSANITIZE
|
||||
// RUN: %clang_cc1 -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 -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: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[CHAR]] }
|
||||
|
||||
char **__attribute__((assume_aligned(0x80000000))) passthrough(char **x) {
|
||||
// CHECK: define i8** @[[PASSTHROUGH:.*]](i8** %[[X:.*]])
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: %[[X_ADDR:.*]] = alloca i8**, align 8
|
||||
// CHECK-NEXT: store i8** %[[X]], i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: ret i8** %[[X_RELOADED]]
|
||||
// CHECK-NEXT: }
|
||||
return x;
|
||||
}
|
||||
|
||||
char **caller(char **x) {
|
||||
// CHECK: define i8** @{{.*}}(i8** %[[X]])
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: %[[X_ADDR]] = alloca i8**, align 8
|
||||
// CHECK-NEXT: store i8** %[[X]], i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[X_RETURNED:.*]] = call i8** @[[PASSTHROUGH]](i8** %[[X_RELOADED]])
|
||||
// CHECK-NEXT: %[[PTRINT:.*]] = ptrtoint i8** %[[X_RETURNED]] to i64
|
||||
// CHECK-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[PTRINT]], 2147483647
|
||||
// CHECK-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
|
||||
// CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8** %[[X_RETURNED]] to i64, !nosanitize
|
||||
// CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize
|
||||
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
|
||||
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 0){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 0){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
|
||||
// CHECK-SANITIZE: [[CONT]]:
|
||||
// CHECK-NEXT: call void @llvm.assume(i1 %[[MASKCOND]])
|
||||
// CHECK-NEXT: ret i8** %[[X_RETURNED]]
|
||||
// CHECK-NEXT: }
|
||||
#line 100
|
||||
return passthrough(x);
|
||||
}
|
28
clang/test/CodeGen/catch-alignment-assumption-blacklist.c
Normal file
28
clang/test/CodeGen/catch-alignment-assumption-blacklist.c
Normal file
@ -0,0 +1,28 @@
|
||||
// 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-LABEL: @baseline
|
||||
void *baseline(void *x) {
|
||||
// CHECK: call void @__ubsan_handle_alignment_assumption(
|
||||
return __builtin_assume_aligned(x, 1);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: blacklist_0
|
||||
__attribute__((no_sanitize("undefined"))) void *blacklist_0(void *x) {
|
||||
return __builtin_assume_aligned(x, 1);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: blacklist_1
|
||||
__attribute__((no_sanitize("alignment"))) void *blacklist_1(void *x) {
|
||||
return __builtin_assume_aligned(x, 1);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: dont_ignore_volatile_ptrs
|
||||
void *dont_ignore_volatile_ptrs(void * volatile x) {
|
||||
// CHECK: call void @__ubsan_handle_alignment_assumption(
|
||||
return __builtin_assume_aligned(x, 1);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: ignore_volatiles
|
||||
void *ignore_volatiles(volatile void * x) {
|
||||
return __builtin_assume_aligned(x, 1);
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-NOSANITIZE
|
||||
// RUN: %clang_cc1 -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 -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: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 35 }, {{.*}}* @[[CHAR]] }
|
||||
|
||||
void *caller(char **x, unsigned long offset) {
|
||||
// CHECK: define i8* @{{.*}}(i8** %[[X:.*]], i64 %[[OFFSET:.*]])
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: %[[X_ADDR:.*]] = alloca i8**, align 8
|
||||
// CHECK-NEXT: %[[OFFSET_ADDR:.*]] = alloca i64, align 8
|
||||
// CHECK-NEXT: store i8** %[[X]], i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: store i64 %[[OFFSET]], i64* %[[OFFSET_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[BITCAST:.*]] = bitcast i8** %[[X_RELOADED]] to i8*
|
||||
// CHECK-NEXT: %[[OFFSET_RELOADED:.*]] = load i64, i64* %[[OFFSET_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[PTRINT:.*]] = ptrtoint i8* %[[BITCAST]] to i64
|
||||
// CHECK-NEXT: %[[OFFSETPTR:.*]] = sub i64 %[[PTRINT]], %[[OFFSET_RELOADED]]
|
||||
// CHECK-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[OFFSETPTR]], 2147483647
|
||||
// CHECK-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
|
||||
// CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8* %[[BITCAST]] to i64, !nosanitize
|
||||
// CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize
|
||||
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
|
||||
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 %[[OFFSET_RELOADED]]){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 %[[OFFSET_RELOADED]]){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
|
||||
// CHECK-SANITIZE: [[CONT]]:
|
||||
// CHECK-NEXT: call void @llvm.assume(i1 %[[MASKCOND]])
|
||||
// CHECK-NEXT: ret i8* %[[BITCAST]]
|
||||
// CHECK-NEXT: }
|
||||
#line 100
|
||||
return __builtin_assume_aligned(x, 0x80000000, offset);
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-NOSANITIZE
|
||||
// RUN: %clang_cc1 -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 -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: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 35 }, {{.*}}* @[[CHAR]] }
|
||||
|
||||
void *caller(char **x) {
|
||||
// CHECK: define i8* @{{.*}}(i8** %[[X:.*]])
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: %[[X_ADDR:.*]] = alloca i8**, align 8
|
||||
// CHECK-NEXT: store i8** %[[X]], i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[BITCAST:.*]] = bitcast i8** %[[X_RELOADED]] to i8*
|
||||
// CHECK-NEXT: %[[PTRINT:.*]] = ptrtoint i8* %[[BITCAST]] to i64
|
||||
// CHECK-NEXT: %[[OFFSETPTR:.*]] = sub i64 %[[PTRINT]], 42
|
||||
// CHECK-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[OFFSETPTR]], 2147483647
|
||||
// CHECK-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
|
||||
// CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8* %[[BITCAST]] to i64, !nosanitize
|
||||
// CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize
|
||||
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
|
||||
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 42){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 42){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
|
||||
// CHECK-SANITIZE: [[CONT]]:
|
||||
// CHECK-NEXT: call void @llvm.assume(i1 %[[MASKCOND]])
|
||||
// CHECK-NEXT: ret i8* %[[BITCAST]]
|
||||
// CHECK-NEXT: }
|
||||
#line 100
|
||||
return __builtin_assume_aligned(x, 0x80000000, 42);
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-NOSANITIZE
|
||||
// RUN: %clang_cc1 -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 -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: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 35 }, {{.*}}* @[[CHAR]] }
|
||||
|
||||
void *caller(char **x) {
|
||||
// CHECK: define i8* @{{.*}}(i8** %[[X:.*]])
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: %[[X_ADDR:.*]] = alloca i8**, align 8
|
||||
// CHECK-NEXT: store i8** %[[X]], i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[BITCAST:.*]] = bitcast i8** %[[X_RELOADED]] to i8*
|
||||
// CHECK-NEXT: %[[PTRINT:.*]] = ptrtoint i8* %[[BITCAST]] to i64
|
||||
// CHECK-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[PTRINT]], 2147483647
|
||||
// CHECK-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
|
||||
// CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8* %[[BITCAST]] to i64, !nosanitize
|
||||
// CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize
|
||||
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
|
||||
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 0){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 2147483648, i64 0){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
|
||||
// CHECK-SANITIZE: [[CONT]]:
|
||||
// CHECK-NEXT: call void @llvm.assume(i1 %[[MASKCOND]])
|
||||
// CHECK-NEXT: ret i8* %[[BITCAST]]
|
||||
// CHECK-NEXT: }
|
||||
#line 100
|
||||
return __builtin_assume_aligned(x, 0x80000000);
|
||||
}
|
32
clang/test/CodeGen/catch-alignment-assumption-openmp.cpp
Normal file
32
clang/test/CodeGen/catch-alignment-assumption-openmp.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
// RUN: %clang_cc1 -fopenmp-simd -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-NOSANITIZE
|
||||
// RUN: %clang_cc1 -fopenmp-simd -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 -fopenmp-simd -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 -fopenmp-simd -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: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 30 }, {{.*}}* @[[CHAR]] }
|
||||
|
||||
void func(char *data) {
|
||||
// CHECK: define void @{{.*}}(i8* %[[DATA:.*]])
|
||||
// CHECK-NEXT: [[ENTRY:.*]]:
|
||||
// CHECK-NEXT: %[[DATA_ADDR:.*]] = alloca i8*, align 8
|
||||
// CHECK: store i8* %[[DATA]], i8** %[[DATA_ADDR]], align 8
|
||||
// CHECK: %[[DATA_RELOADED:.*]] = load i8*, i8** %[[DATA_ADDR]], align 8
|
||||
// CHECK-NEXT: %[[PTRINT:.*]] = ptrtoint i8* %[[DATA_RELOADED]] to i64
|
||||
// CHECK-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[PTRINT]], 1073741823
|
||||
// CHECK-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
|
||||
// CHECK-SANITIZE-NEXT: %[[PTRINT_DUP:.*]] = ptrtoint i8* %[[DATA_RELOADED]] to i64, !nosanitize
|
||||
// CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:.*]], label %[[HANDLER_ALIGNMENT_ASSUMPTION:[^,]+]],{{.*}} !nosanitize
|
||||
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
|
||||
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 1073741824, i64 0){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(i8* bitcast ({ {{{.*}}}, {{{.*}}}, {{{.*}}}* }* @[[LINE_100_ALIGNMENT_ASSUMPTION]] to i8*), i64 %[[PTRINT_DUP]], i64 1073741824, i64 0){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
|
||||
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
|
||||
// CHECK-SANITIZE: [[CONT]]:
|
||||
// CHECK-NEXT: call void @llvm.assume(i1 %[[MASKCOND]])
|
||||
|
||||
#line 100
|
||||
#pragma omp for simd aligned(data : 0x40000000)
|
||||
for (int x = 0; x < 1; x++)
|
||||
data[x] = data[x];
|
||||
}
|
Loading…
Reference in New Issue
Block a user