Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/swift-4.1-branch' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
swift-ci committed Oct 17, 2017
2 parents 12a3c42 + fa51a8d commit ffe2d63
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 21 deletions.
12 changes: 10 additions & 2 deletions lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,15 @@ static void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn) {
Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
}

/// Return the UBSan prologue signature for \p FD if one is available.
static llvm::Constant *getPrologueSignature(CodeGenModule &CGM,
const FunctionDecl *FD) {
if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
if (!MD->isStatic())
return nullptr;
return CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM);
}

void CodeGenFunction::StartFunction(GlobalDecl GD,
QualType RetTy,
llvm::Function *Fn,
Expand Down Expand Up @@ -865,8 +874,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
// prologue data.
if (getLangOpts().CPlusPlus && SanOpts.has(SanitizerKind::Function)) {
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
if (llvm::Constant *PrologueSig =
CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) {
if (llvm::Constant *PrologueSig = getPrologueSignature(CGM, FD)) {
llvm::Constant *FTRTTIConst =
CGM.GetAddrOfRTTIDescriptor(FD->getType(), /*ForEH=*/true);
llvm::Constant *FTRTTIConstEncoded =
Expand Down
40 changes: 29 additions & 11 deletions lib/CodeGen/CoverageMappingGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,22 @@ struct CounterCoverageMappingBuilder
handleFileExit(getEnd(S));
}

/// Determine whether the final deferred region emitted in \p Body should be
/// discarded.
static bool discardFinalDeferredRegionInDecl(Stmt *Body) {
if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
Stmt *LastStmt = CS->body_back();
if (auto *IfElse = dyn_cast<IfStmt>(LastStmt)) {
if (auto *Else = dyn_cast_or_null<CompoundStmt>(IfElse->getElse()))
LastStmt = Else->body_back();
else
LastStmt = IfElse->getElse();
}
return dyn_cast_or_null<ReturnStmt>(LastStmt);
}
return false;
}

void VisitDecl(const Decl *D) {
assert(!DeferredRegion && "Deferred region never completed");

Expand All @@ -770,14 +786,14 @@ struct CounterCoverageMappingBuilder
Counter ExitCount = propagateCounts(getRegionCounter(Body), Body);
assert(RegionStack.empty() && "Regions entered but never exited");

// Special case: if the last statement is a return, throw away the
// deferred region. This allows the closing brace to have a count.
if (auto *CS = dyn_cast_or_null<CompoundStmt>(Body))
if (dyn_cast_or_null<ReturnStmt>(CS->body_back()))
if (DeferredRegion) {
// Complete (or discard) any deferred regions introduced by the last
// statement.
if (discardFinalDeferredRegionInDecl(Body))
DeferredRegion = None;

// Complete any deferred regions introduced by the last statement.
popRegions(completeDeferred(ExitCount, getEnd(Body)));
else
popRegions(completeDeferred(ExitCount, getEnd(Body)));
}
}

void VisitReturnStmt(const ReturnStmt *S) {
Expand Down Expand Up @@ -1083,16 +1099,18 @@ struct CounterCoverageMappingBuilder
}

void VisitBinLAnd(const BinaryOperator *E) {
extendRegion(E);
Visit(E->getLHS());
extendRegion(E->getLHS());
propagateCounts(getRegion().getCounter(), E->getLHS());
handleFileExit(getEnd(E->getLHS()));

extendRegion(E->getRHS());
propagateCounts(getRegionCounter(E), E->getRHS());
}

void VisitBinLOr(const BinaryOperator *E) {
extendRegion(E);
Visit(E->getLHS());
extendRegion(E->getLHS());
propagateCounts(getRegion().getCounter(), E->getLHS());
handleFileExit(getEnd(E->getLHS()));

extendRegion(E->getRHS());
propagateCounts(getRegionCounter(E), E->getRHS());
Expand Down
60 changes: 60 additions & 0 deletions test/CodeGenCXX/catch-undef-behavior.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,66 @@ void indirect_function_call(void (*p)(int)) {
p(42);
}

namespace FunctionSanitizerVirtualCalls {
struct A {
virtual void f() {}
virtual void g() {}
void h() {}
};

struct B : virtual A {
virtual void b() {}
virtual void f();
void g() final {}
static void q() {}
};

void B::f() {}

void force_irgen() {
A a;
a.g();
a.h();

B b;
b.f();
b.b();
b.g();
B::q();
}

// CHECK-LABEL: define void @_ZN29FunctionSanitizerVirtualCalls1B1fEv
// CHECK-NOT: prologue
//
// CHECK-LABEL: define void @_ZTv0_n24_N29FunctionSanitizerVirtualCalls1B1fEv
// CHECK-NOT: prologue
//
// CHECK-LABEL: define void @_ZN29FunctionSanitizerVirtualCalls11force_irgenEv()
// CHECK: prologue
//
// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1AC1Ev
// CHECK-NOT: prologue
//
// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1A1gEv
// CHECK-NOT: prologue
//
// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1A1hEv
// CHECK-NOT: prologue
//
// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1BC1Ev
// CHECK-NOT: prologue
//
// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1bEv
// CHECK-NOT: prologue
//
// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1gEv
// CHECK-NOT: prologue
//
// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1qEv
// CHECK: prologue

}

namespace UpcastPointerTest {
struct S {};
struct T : S { double d; };
Expand Down
22 changes: 21 additions & 1 deletion test/CoverageMapping/deferred-region.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,28 @@ void baz() { // CHECK: [[@LINE]]:12 -> [[@LINE+2]]:2
// CHECK-LABEL: _Z3mazv:
void maz() {
if (true)
return; // CHECK: Gap,File 0, [[@LINE]]:11 -> 36:3 = (#0 - #1)
return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)

return; // CHECK-NOT: Gap
}

// CHECK-LABEL: _Z4maazv:
void maaz() {
if (true)
return; // CHECK: Gap,File 0, [[@LINE]]:11
else
return; // CHECK-NOT: Gap,File 0, [[@LINE]]
}

// CHECK-LABEL: _Z5maaazv:
void maaaz() {
if (true) {
return;
} else { // CHECK: Gap,File 0, [[@LINE]]:4 -> [[@LINE]]:10
return; // CHECK-NOT: Gap,File 0, [[@LINE]]
}
}

// CHECK-LABEL: _Z3bari:
void bar(int x) {
IF (x)
Expand Down Expand Up @@ -158,6 +175,9 @@ int main() {
foo(1);
fooo(0);
fooo(1);
maz();
maaz();
maaaz();
baz();
bar(0);
bar(1);
Expand Down
15 changes: 10 additions & 5 deletions test/CoverageMapping/logical.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name logical.cpp %s | FileCheck %s

int main() { // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+10]]:2 = #0
int main() { // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+15]]:2 = #0
bool bt = true;
bool bf = false;
bool a = bt && bf; // CHECK-NEXT: File 0, [[@LINE]]:18 -> [[@LINE]]:20 = #1
a = bt &&
bool a = bt && bf; // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE]]:14 = #0
// CHECK-NEXT: File 0, [[@LINE-1]]:18 -> [[@LINE-1]]:20 = #1

a = bt && // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:9 = #0
bf; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:9 = #2
a = bf || bt; // CHECK-NEXT: File 0, [[@LINE]]:13 -> [[@LINE]]:15 = #3
a = bf ||

a = bf || bt; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:9 = #0
// CHECK-NEXT: File 0, [[@LINE-1]]:13 -> [[@LINE-1]]:15 = #3

a = bf || // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:9 = #0
bt; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:9 = #4
return 0;
}
6 changes: 4 additions & 2 deletions test/CoverageMapping/macro-expansion.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@
// CHECK-NEXT: Expansion,File 4, [[@LINE+2]]:20 -> [[@LINE+2]]:22 = (#0 + #8)
// CHECK-NEXT: File 4, [[@LINE+1]]:36 -> [[@LINE+1]]:37 = (#0 + #8)
#define M3(x) do { M2(x); } while (0)
// CHECK-NEXT: File 5, [[@LINE+2]]:15 -> [[@LINE+2]]:27 = #0
// CHECK-NEXT: File 5, [[@LINE+3]]:15 -> [[@LINE+3]]:27 = #0
// CHECK-NEXT: File 5, [[@LINE+2]]:16 -> [[@LINE+2]]:19 = #0
// CHECK-NEXT: File 5, [[@LINE+1]]:23 -> [[@LINE+1]]:26 = #12
#define M4(x) ((x) && (x))
// CHECK-NEXT: File 6, [[@LINE+2]]:15 -> [[@LINE+2]]:27 = #0
// CHECK-NEXT: File 6, [[@LINE+3]]:15 -> [[@LINE+3]]:27 = #0
// CHECK-NEXT: File 6, [[@LINE+2]]:16 -> [[@LINE+2]]:19 = #0
// CHECK-NEXT: File 6, [[@LINE+1]]:23 -> [[@LINE+1]]:26 = #14
#define M5(x) ((x) || (x))
// CHECK-NEXT: File 7, [[@LINE+1]]:15 -> [[@LINE+1]]:26 = #0
Expand Down

0 comments on commit ffe2d63

Please sign in to comment.